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
56namespace std _GLIBCXX_VISIBILITY(default)
58_GLIBCXX_BEGIN_NAMESPACE_VERSION
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 =
'/';
219 path(string_type&& __source);
221 template<
typename _Source,
222 typename _Require = __detail::_Path<_Source>>
223 path(_Source
const& __source)
224 : _M_pathname(_S_convert(__detail::_S_range_begin(__source),
225 __detail::_S_range_end(__source)))
226 { _M_split_cmpts(); }
228 template<
typename _InputIterator,
229 typename _Require = __detail::_Path<_InputIterator, _InputIterator>>
230 path(_InputIterator __first, _InputIterator __last)
231 : _M_pathname(_S_convert(__first, __last))
232 { _M_split_cmpts(); }
234 template<
typename _Source,
235 typename _Require = __detail::_Path<_Source>,
236 typename _Require2 = __detail::__value_type_is_char<_Source>>
237 path(_Source
const& __source,
const locale& __loc)
238 : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source),
239 __detail::_S_range_end(__source), __loc))
240 { _M_split_cmpts(); }
242 template<
typename _InputIterator,
243 typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
244 typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
245 path(_InputIterator __first, _InputIterator __last,
const locale& __loc)
246 : _M_pathname(_S_convert_loc(__first, __last, __loc))
247 { _M_split_cmpts(); }
254 path& operator=(
path&& __p)
noexcept;
255 path& operator=(string_type&& __source);
256 path& assign(string_type&& __source);
258 template<
typename _Source>
259 __detail::_Path<_Source>&
260 operator=(_Source
const& __source)
261 {
return *
this =
path(__source); }
263 template<
typename _Source>
264 __detail::_Path<_Source>&
265 assign(_Source
const& __source)
266 {
return *
this =
path(__source); }
268 template<
typename _InputIterator>
269 __detail::_Path<_InputIterator, _InputIterator>&
270 assign(_InputIterator __first, _InputIterator __last)
271 {
return *
this =
path(__first, __last); }
275 path& operator/=(
const path& __p) {
return _M_append(__p._M_pathname); }
277 template<
typename _Source>
278 __detail::_Path<_Source>&
279 operator/=(_Source
const& __source)
280 {
return append(__source); }
282 template<
typename _Source>
283 __detail::_Path<_Source>&
284 append(_Source
const& __source)
286 return _M_append(_S_convert(__detail::_S_range_begin(__source),
287 __detail::_S_range_end(__source)));
290 template<
typename _InputIterator>
291 __detail::_Path<_InputIterator, _InputIterator>&
292 append(_InputIterator __first, _InputIterator __last)
293 {
return _M_append(_S_convert(__first, __last)); }
298 path& operator+=(
const string_type& __x);
299 path& operator+=(
const value_type* __x);
300 path& operator+=(value_type __x);
301#if __cplusplus >= 201402L
305 template<
typename _Source>
306 __detail::_Path<_Source>&
307 operator+=(_Source
const& __x) {
return concat(__x); }
309 template<
typename _CharT>
310 __detail::_Path<_CharT*, _CharT*>&
311 operator+=(_CharT __x);
313 template<
typename _Source>
314 __detail::_Path<_Source>&
315 concat(_Source
const& __x)
317 return *
this += _S_convert(__detail::_S_range_begin(__x),
318 __detail::_S_range_end(__x));
321 template<
typename _InputIterator>
322 __detail::_Path<_InputIterator, _InputIterator>&
323 concat(_InputIterator __first, _InputIterator __last)
324 {
return *
this += _S_convert(__first, __last); }
328 void clear()
noexcept { _M_pathname.clear(); _M_split_cmpts(); }
330 path& make_preferred();
331 path& remove_filename();
332 path& replace_filename(
const path& __replacement);
333 path& replace_extension(
const path& __replacement =
path());
339 const string_type& native()
const noexcept {
return _M_pathname; }
340 const value_type* c_str()
const noexcept {
return _M_pathname.c_str(); }
341 operator string_type()
const {
return _M_pathname; }
343 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
344 typename _Allocator = std::allocator<_CharT>>
346 string(
const _Allocator& __a = _Allocator())
const;
349#if _GLIBCXX_USE_WCHAR_T
352#ifdef _GLIBCXX_USE_CHAR8_T
353 __attribute__((__abi_tag__(
"__u8")))
354 std::u8string u8string()
const;
362 template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT>,
363 typename _Allocator = std::allocator<_CharT>>
365 generic_string(
const _Allocator& __a = _Allocator())
const;
368#if _GLIBCXX_USE_WCHAR_T
371#ifdef _GLIBCXX_USE_CHAR8_T
372 __attribute__((__abi_tag__(
"__u8")))
373 std::u8string generic_u8string()
const;
382 int compare(
const path& __p)
const noexcept;
383 int compare(
const string_type& __s)
const;
384 int compare(
const value_type* __s)
const;
385#if __cplusplus >= 201402L
391 path root_name()
const;
392 path root_directory()
const;
393 path root_path()
const;
394 path relative_path()
const;
395 path parent_path()
const;
396 path filename()
const;
398 path extension()
const;
402 _GLIBCXX_NODISCARD
bool empty()
const noexcept {
return _M_pathname.empty(); }
403 bool has_root_name()
const;
404 bool has_root_directory()
const;
405 bool has_root_path()
const;
406 bool has_relative_path()
const;
407 bool has_parent_path()
const;
408 bool has_filename()
const;
409 bool has_stem()
const;
410 bool has_extension()
const;
411 bool is_absolute()
const;
412 bool is_relative()
const {
return !is_absolute(); }
423 template<
typename _InputIterator,
426 =
typename std::remove_cv<typename _Traits::value_type>::type>
428 _S_string_from_iter(_InputIterator __source)
431 for (_CharT __ch = *__source; __ch != _CharT(); __ch = *++__source)
438 enum class _Type :
unsigned char {
439 _Multi, _Root_name, _Root_dir, _Filename
442 path(string_type __str, _Type __type);
444 enum class _Split { _Stem, _Extension };
446 path& _M_append(
const string_type& __str)
448 if (!_M_pathname.empty() && !_S_is_dir_sep(_M_pathname.back())
449 && !__str.empty() && !_S_is_dir_sep(__str.front()))
450 _M_pathname += preferred_separator;
451 _M_pathname += __str;
458 template<
typename _CharT>
462 _S_convert(value_type* __src, __detail::__nul_terminated)
463 {
return string_type(__src); }
466 _S_convert(
const value_type* __src, __detail::__nul_terminated)
467 {
return string_type(__src); }
469 template<
typename _Iter>
471 _S_convert(_Iter __first, _Iter __last)
474 return _Cvt<typename remove_cv<__value_type>::type>::
475 _S_convert(__first, __last);
478 template<
typename _InputIterator>
480 _S_convert(_InputIterator __src, __detail::__nul_terminated)
482 auto __s = _S_string_from_iter(__src);
483 return _S_convert(__s.c_str(), __s.c_str() + __s.size());
487 _S_convert_loc(
const char* __first,
const char* __last,
491 _S_convert_loc(
char* __first,
char* __last,
const std::locale& __loc)
493 return _S_convert_loc(
const_cast<const char*
>(__first),
494 const_cast<const char*
>(__last), __loc);
497 template<
typename _Iter>
499 _S_convert_loc(_Iter __first, _Iter __last,
const std::locale& __loc)
502 return _S_convert_loc(__str.
data(), __str.
data()+__str.
size(), __loc);
505 template<
typename _InputIterator>
507 _S_convert_loc(_InputIterator __src, __detail::__nul_terminated,
510 const std::string __s = _S_string_from_iter(__src);
511 return _S_convert_loc(__s.
data(), __s.
data() + __s.
size(), __loc);
514 static bool _S_is_dir_sep(value_type __ch)
516#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
517 return __ch == L
'/' || __ch == preferred_separator;
523 void _M_split_cmpts();
525 void _M_add_root_name(
size_t __n);
526 void _M_add_root_dir(
size_t __pos);
527 void _M_add_filename(
size_t __pos,
size_t __n);
529 string_type _M_pathname;
532 using _List = _GLIBCXX_STD_C::vector<_Cmpt>;
534 _Type _M_type = _Type::_Multi;
540#if __cpp_concepts >= 201907L
544 { __lhs.swap(__rhs); }
546 inline void swap(path& __lhs, path& __rhs)
noexcept { __lhs.swap(__rhs); }
550 size_t hash_value(
const path& __p)
noexcept;
553 inline bool operator<(
const path& __lhs,
const path& __rhs)
noexcept;
556 inline bool operator<=(
const path& __lhs,
const path& __rhs)
noexcept
557 {
return !(__rhs < __lhs); }
560 inline bool operator>(
const path& __lhs,
const path& __rhs)
noexcept
561 {
return __rhs < __lhs; }
564 inline bool operator>=(
const path& __lhs,
const path& __rhs)
noexcept
565 {
return !(__lhs < __rhs); }
568 inline bool operator==(
const path& __lhs,
const path& __rhs)
noexcept;
571 inline bool operator!=(
const path& __lhs,
const path& __rhs)
noexcept
572 {
return !(__lhs == __rhs); }
575 inline path
operator/(
const path& __lhs,
const path& __rhs)
577 path __result(__lhs);
583 template<
typename _CharT,
typename _Traits>
584 basic_ostream<_CharT, _Traits>&
585 operator<<(basic_ostream<_CharT, _Traits>& __os,
const path& __p)
587 auto __tmp = __p.string<_CharT, _Traits>();
588 using __quoted_string
590 __os << __quoted_string{__tmp, _CharT(
'"'), _CharT(
'\\')};
595 template<
typename _CharT,
typename _Traits>
596 basic_istream<_CharT, _Traits>&
597 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
599 basic_string<_CharT, _Traits> __tmp;
600 using __quoted_string
602 if (__is >> __quoted_string{ __tmp, _CharT(
'"'), _CharT(
'\\') })
608#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
609 template<
typename _InputIterator>
611 __u8path(_InputIterator __first, _InputIterator __last,
char)
614 std::codecvt_utf8_utf16<path::value_type> __cvt;
615 path::string_type __tmp;
617 const char*
const __ptr = __u8str.
data();
618 if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
619 return path{ __tmp };
620 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
621 "Cannot convert character sequence",
625#ifdef _GLIBCXX_USE_CHAR8_T
626 template<
typename _InputIterator>
628 __u8path(_InputIterator __first, _InputIterator __last,
char8_t)
630 return path{ __first, __last };
635 template<
typename _InputIterator,
636 typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
638 __detail::__value_type_is_char_or_char8_t<_InputIterator>>
640 u8path(_InputIterator __first, _InputIterator __last)
642#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
643 return __u8path(__first, __last, _CharT{});
645 return path{ __first, __last };
650#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
652 __u8path(
const string& __s,
char)
654 return filesystem::u8path(__s.data(), __s.data() + __s.size());
657 template<
typename _Source>
658 inline __enable_if_t<is_convertible<const _Source&, string>::value, path>
659 __u8path(
const _Source& __source,
char)
662 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
665 template<
typename _Source>
666 inline __enable_if_t<!is_convertible<const _Source&, string>::value, path>
667 __u8path(
const _Source& __source,
char)
669 std::string __s = path::_S_string_from_iter(__source);
670 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
673#ifdef _GLIBCXX_USE_CHAR8_T
674 template<
typename _Source>
676 __u8path(
const _Source& __source,
char8_t)
678 return path{ __source };
683 template<
typename _Source,
684 typename _Require = __detail::_Path<_Source>,
686 __detail::__value_type_is_char_or_char8_t<_Source>>
688 u8path(
const _Source& __source)
690#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
691 return __u8path(__source, _CharT{});
693 return path{ __source };
712 :
system_error(__ec, __what_arg), _M_path1(__p1), _M_path2(__p2)
717 const path& path1()
const noexcept {
return _M_path1; }
718 const path& path2()
const noexcept {
return _M_path2; }
719 const char*
what() const noexcept {
return _M_what.
c_str(); }
730 struct path::_Cmpt :
path
732 _Cmpt(string_type __s, _Type __t,
size_t __pos)
733 :
path(
std::move(__s), __t), _M_pos(__pos) { }
735 _Cmpt() : _M_pos(-1) { }
742 struct path::_Cvt<path::value_type>
747 using __codecvt_utf8_to_wide = _Cvt;
749 template<
typename _WStr>
751 __str_codecvt_in_all(
const char*,
const char*,
752 _WStr&, __codecvt_utf8_to_wide&)
noexcept
755 template<
typename _Iter>
757 _S_convert(_Iter __first, _Iter __last)
758 {
return string_type{__first, __last}; }
762 template<
typename _CharT>
768 using __codecvt_utf8_to_wchar
769 = __conditional_t<
sizeof(wchar_t) ==
sizeof(
char32_t),
770 std::codecvt_utf8<wchar_t>,
771 std::codecvt_utf8_utf16<wchar_t>>;
775 struct __codecvt_utf8_to_utfNN :
std::codecvt<_CharT, char, mbstate_t>
780 using __codecvt_utf8_to_wide
781 = __conditional_t<is_same<_CharT, wchar_t>::value,
782 __codecvt_utf8_to_wchar,
783 __codecvt_utf8_to_utfNN>;
785#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
786#ifdef _GLIBCXX_USE_CHAR8_T
788 _S_wconvert(
const char8_t* __f,
const char8_t* __l,
const char8_t*)
790 const char* __f2 = (
const char*)__f;
791 const char* __l2 = (
const char*)__l;
793 std::codecvt_utf8_utf16<wchar_t> __wcvt;
794 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
800 _S_wconvert(
const char* __f,
const char* __l,
const char*)
802 std::codecvt_utf8_utf16<wchar_t> __cvt;
804 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
806 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
807 "Cannot convert character sequence",
812 _S_wconvert(
const _CharT* __f,
const _CharT* __l,
const void*)
814 __codecvt_utf8_to_wide __cvt;
816 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
818 const char* __f2 = __str.
data();
819 const char* __l2 = __f2 + __str.
size();
820 std::codecvt_utf8_utf16<wchar_t> __wcvt;
822 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
825 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
826 "Cannot convert character sequence",
831 _S_convert(
const _CharT* __f,
const _CharT* __l)
833 return _S_wconvert(__f, __l, (
const _CharT*)
nullptr);
837 _S_convert(
const _CharT* __f,
const _CharT* __l)
839#ifdef _GLIBCXX_USE_CHAR8_T
840 if constexpr (is_same<_CharT, char8_t>::value)
841 return string_type(__f, __l);
845 __codecvt_utf8_to_wide __cvt;
847 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
849 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
850 "Cannot convert character sequence",
857 _S_convert(_CharT* __f, _CharT* __l)
859 return _S_convert(
const_cast<const _CharT*
>(__f),
860 const_cast<const _CharT*
>(__l));
863 template<
typename _Iter>
865 _S_convert(_Iter __first, _Iter __last)
868 return _S_convert(__str.
data(), __str.
data() + __str.
size());
871 template<
typename _Iter,
typename _Cont>
873 _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
874 __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
875 {
return _S_convert(__first.base(), __last.base()); }
883 using difference_type = std::ptrdiff_t;
889 iterator() noexcept : _M_path(
nullptr), _M_cur(), _M_at_end() { }
900 {
auto __tmp = *
this; ++*
this;
return __tmp; }
905 {
auto __tmp = *
this; --*
this;
return __tmp; }
909 {
return __lhs._M_equals(__rhs); }
913 {
return !__lhs._M_equals(__rhs); }
918 iterator(
const path* __path, path::_List::const_iterator __iter) noexcept
919 : _M_path(__path), _M_cur(__iter), _M_at_end()
923 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
926 bool _M_equals(
iterator)
const noexcept;
929 path::_List::const_iterator _M_cur;
934 path::path() noexcept = default;
941 : _M_pathname(
std::
move(__p._M_pathname)),
942 _M_cmpts(__p._M_cmpts),
947 path::path(string_type&& __source)
948 : _M_pathname(
std::
move(__source))
949 { _M_split_cmpts(); }
952 path::path(string_type __str, _Type __type)
953 : _M_pathname(__str), _M_type(__type)
955 __glibcxx_assert(!empty());
956 __glibcxx_assert(_M_type != _Type::_Multi);
960 path::~path() =
default;
963 path::operator=(
const path& __p) =
default;
966 path::operator=(path&& __p)
noexcept
968 _M_pathname =
std::move(__p._M_pathname);
970 _M_type = __p._M_type;
976 path::operator=(string_type&& __source)
977 {
return *
this = path(
std::move(__source)); }
980 path::assign(string_type&& __source)
981 {
return *
this = path(
std::move(__source)); }
984 path::operator+=(
const path& __p)
986 return operator+=(__p.native());
990 path::operator+=(
const string_type& __x)
998 path::operator+=(
const value_type* __x)
1006 path::operator+=(value_type __x)
1013#if __cplusplus >= 201402L
1015 path::operator+=(basic_string_view<value_type> __x)
1017 _M_pathname.append(__x.data(), __x.size());
1023 template<
typename _CharT>
1024 inline __detail::_Path<_CharT*, _CharT*>&
1025 path::operator+=(_CharT __x)
1028 return concat(__addr, __addr + 1);
1032 path::make_preferred()
1034#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1035 std::replace(_M_pathname.begin(), _M_pathname.end(), L
'/',
1036 preferred_separator);
1041 inline void path::swap(path& __rhs)
noexcept
1043 _M_pathname.swap(__rhs._M_pathname);
1044 _M_cmpts.swap(__rhs._M_cmpts);
1048 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1050 path::string(
const _Allocator& __a)
const
1052 if _GLIBCXX_CONSTEXPR (is_same<_CharT, value_type>::value)
1053 return { _M_pathname.
begin(), _M_pathname.end(), __a };
1055 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1057 const value_type* __first = _M_pathname.data();
1058 const value_type* __last = __first + _M_pathname.size();
1060#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1061 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1062 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1066 codecvt_utf8_utf16<value_type> __cvt;
1067 _String __u8str{_CharAlloc{__a}};
1068 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1073 operator()(
const _String& __from, _String&,
true_type)
1077 operator()(
const _String& __from, _WString& __to,
false_type)
1079#ifdef _GLIBCXX_USE_CHAR8_T
1080 if constexpr (is_same<_CharT, char8_t>::value)
1082 __to.assign(__from.begin(), __from.end());
1089 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1090 const char* __f = __from.data();
1091 const char* __l = __f + __from.size();
1092 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1098 _WString __wstr(__a);
1099 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1103#ifdef _GLIBCXX_USE_CHAR8_T
1104 if constexpr (is_same<_CharT, char8_t>::value)
1105 return _WString(__first, __last, __a);
1109 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1110 _WString __wstr(__a);
1111 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1115 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1116 "Cannot convert character sequence",
1121 path::string()
const {
return string<char>(); }
1123#if _GLIBCXX_USE_WCHAR_T
1125 path::wstring()
const {
return string<wchar_t>(); }
1128#ifdef _GLIBCXX_USE_CHAR8_T
1129 inline std::u8string
1130 path::u8string()
const {
return string<char8_t>(); }
1133 path::u8string()
const
1135#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1138 std::codecvt_utf8_utf16<value_type> __cvt;
1139 const value_type* __first = _M_pathname.data();
1140 const value_type* __last = __first + _M_pathname.size();
1141 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1143 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1144 "Cannot convert character sequence",
1153 path::u16string()
const {
return string<char16_t>(); }
1156 path::u32string()
const {
return string<char32_t>(); }
1158 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1160 path::generic_string(
const _Allocator& __a)
const
1162#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1163 const _CharT __slash = is_same<_CharT, wchar_t>::value
1167 const _CharT __slash = _CharT(
'/');
1169 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1170 __str.
reserve(_M_pathname.size());
1171 bool __add_slash =
false;
1172 for (
auto& __elem : *this)
1174 if (__elem._M_type == _Type::_Root_dir)
1181 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1182 __add_slash = __elem._M_type == _Type::_Filename;
1188 path::generic_string()
const {
return generic_string<char>(); }
1190#if _GLIBCXX_USE_WCHAR_T
1192 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1195#ifdef _GLIBCXX_USE_CHAR8_T
1196 inline std::u8string
1197 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1200 path::generic_u8string()
const {
return generic_string<char>(); }
1204 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1207 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1210 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1213 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1215#if __cplusplus >= 201402L
1217 path::compare(basic_string_view<value_type> __s)
const
1218 {
return compare(path(__s)); }
1222 path::filename()
const {
return empty() ? path() : *--end(); }
1227 auto ext = _M_find_extension();
1228 if (ext.first && ext.second != 0)
1229 return path{ext.first->substr(0, ext.second)};
1234 path::extension()
const
1236 auto ext = _M_find_extension();
1238 return path{ext.first->substr(ext.second)};
1243 path::has_stem()
const
1245 auto ext = _M_find_extension();
1246 return ext.first && ext.second != 0;
1250 path::has_extension()
const
1252 auto ext = _M_find_extension();
1257 path::is_absolute()
const
1259#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1260 return has_root_name() && has_root_directory();
1262 return has_root_directory();
1266 inline path::iterator
1267 path::begin() const noexcept
1269 if (_M_type == _Type::_Multi)
1270 return iterator(
this, _M_cmpts.begin());
1271 return iterator(
this,
false);
1274 inline path::iterator
1275 path::end() const noexcept
1277 if (_M_type == _Type::_Multi)
1278 return iterator(
this, _M_cmpts.end());
1279 return iterator(
this,
true);
1282 inline path::iterator&
1283 path::iterator::operator++() noexcept
1285 __glibcxx_assert(_M_path !=
nullptr);
1286 if (_M_path->_M_type == _Type::_Multi)
1288 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1293 __glibcxx_assert(!_M_at_end);
1299 inline path::iterator&
1300 path::iterator::operator--() noexcept
1302 __glibcxx_assert(_M_path !=
nullptr);
1303 if (_M_path->_M_type == _Type::_Multi)
1305 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1310 __glibcxx_assert(_M_at_end);
1316 inline path::iterator::reference
1317 path::iterator::operator*() const noexcept
1319 __glibcxx_assert(_M_path !=
nullptr);
1320 if (_M_path->_M_type == _Type::_Multi)
1322 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1329 path::iterator::_M_equals(iterator __rhs)
const noexcept
1331 if (_M_path != __rhs._M_path)
1333 if (_M_path ==
nullptr)
1335 if (_M_path->_M_type == path::_Type::_Multi)
1336 return _M_cur == __rhs._M_cur;
1337 return _M_at_end == __rhs._M_at_end;
1344 inline bool operator<(
const path& __lhs,
const path& __rhs)
noexcept
1345 {
return __lhs.compare(__rhs) < 0; }
1347 inline bool operator==(
const path& __lhs,
const path& __rhs)
noexcept
1348 {
return __lhs.compare(__rhs) == 0; }
1351_GLIBCXX_END_NAMESPACE_CXX11
1356_GLIBCXX_END_NAMESPACE_VERSION
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
error_code make_error_code(future_errc __errc) noexcept
Overload of make_error_code for future_errc.
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 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.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
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.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
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.
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.
Primary class template codecvt.
Managing sequences of characters and character-like objects.
void push_back(_CharT __c)
Append a single character.
const _CharT * data() const noexcept
Return const pointer to 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 * c_str() const noexcept
Return const pointer to null-terminated contents.
static const size_type npos
Value returned by various member functions when they fail.
Traits class for iterators.
Container class for localization functionality.
Struct for delimited strings.
Struct holding two objects of arbitrary type.
Bidirectional iterators support a superset of forward iterator operations.
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.
[concept.same], concept same_as