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());
335 void swap(
path& __rhs)
noexcept;
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 inline void swap(
path& __lhs,
path& __rhs)
noexcept { __lhs.swap(__rhs); }
543 size_t hash_value(
const path& __p)
noexcept;
546 inline bool operator<(
const path& __lhs,
const path& __rhs)
noexcept;
549 inline bool operator<=(
const path& __lhs,
const path& __rhs)
noexcept
550 {
return !(__rhs < __lhs); }
553 inline bool operator>(
const path& __lhs,
const path& __rhs)
noexcept
554 {
return __rhs < __lhs; }
557 inline bool operator>=(
const path& __lhs,
const path& __rhs)
noexcept
558 {
return !(__lhs < __rhs); }
561 inline bool operator==(
const path& __lhs,
const path& __rhs)
noexcept;
564 inline bool operator!=(
const path& __lhs,
const path& __rhs)
noexcept
565 {
return !(__lhs == __rhs); }
568 inline path
operator/(
const path& __lhs,
const path& __rhs)
570 path __result(__lhs);
576 template<
typename _CharT,
typename _Traits>
577 basic_ostream<_CharT, _Traits>&
578 operator<<(basic_ostream<_CharT, _Traits>& __os,
const path& __p)
580 auto __tmp = __p.string<_CharT, _Traits>();
581 using __quoted_string
583 __os << __quoted_string{__tmp, _CharT(
'"'), _CharT(
'\\')};
588 template<
typename _CharT,
typename _Traits>
589 basic_istream<_CharT, _Traits>&
590 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
592 basic_string<_CharT, _Traits> __tmp;
593 using __quoted_string
595 if (__is >> __quoted_string{ __tmp, _CharT(
'"'), _CharT(
'\\') })
601#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
602 template<
typename _InputIterator>
604 __u8path(_InputIterator __first, _InputIterator __last,
char)
607 std::codecvt_utf8_utf16<path::value_type> __cvt;
608 path::string_type __tmp;
610 const char*
const __ptr = __u8str.
data();
611 if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
612 return path{ __tmp };
613 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
614 "Cannot convert character sequence",
615 std::make_error_code(errc::illegal_byte_sequence)));
618#ifdef _GLIBCXX_USE_CHAR8_T
619 template<
typename _InputIterator>
621 __u8path(_InputIterator __first, _InputIterator __last,
char8_t)
623 return path{ __first, __last };
628 template<
typename _InputIterator,
629 typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
631 __detail::__value_type_is_char_or_char8_t<_InputIterator>>
633 u8path(_InputIterator __first, _InputIterator __last)
635#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
636 return __u8path(__first, __last, _CharT{});
638 return path{ __first, __last };
643#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
645 __u8path(
const string& __s,
char)
647 return filesystem::u8path(__s.data(), __s.data() + __s.size());
650 template<
typename _Source>
651 inline __enable_if_t<is_convertible<const _Source&, string>::value, path>
652 __u8path(
const _Source& __source,
char)
655 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
658 template<
typename _Source>
659 inline __enable_if_t<!is_convertible<const _Source&, string>::value, path>
660 __u8path(
const _Source& __source,
char)
662 std::string __s = path::_S_string_from_iter(__source);
663 return filesystem::u8path(__s.
data(), __s.
data() + __s.
size());
666#ifdef _GLIBCXX_USE_CHAR8_T
667 template<
typename _Source>
669 __u8path(
const _Source& __source,
char8_t)
671 return path{ __source };
676 template<
typename _Source,
677 typename _Require = __detail::_Path<_Source>,
679 __detail::__value_type_is_char_or_char8_t<_Source>>
681 u8path(
const _Source& __source)
683#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
684 return __u8path(__source, _CharT{});
686 return path{ __source };
705 :
system_error(__ec, __what_arg), _M_path1(__p1), _M_path2(__p2)
710 const path& path1()
const noexcept {
return _M_path1; }
711 const path& path2()
const noexcept {
return _M_path2; }
712 const char*
what() const noexcept {
return _M_what.
c_str(); }
723 struct path::_Cmpt :
path
725 _Cmpt(string_type __s, _Type __t,
size_t __pos)
728 _Cmpt() : _M_pos(-1) { }
735 struct path::_Cvt<path::value_type>
740 using __codecvt_utf8_to_wide = _Cvt;
742 template<
typename _WStr>
744 __str_codecvt_in_all(
const char*,
const char*,
745 _WStr&, __codecvt_utf8_to_wide&)
noexcept
748 template<
typename _Iter>
750 _S_convert(_Iter __first, _Iter __last)
751 {
return string_type{__first, __last}; }
755 template<
typename _CharT>
761 using __codecvt_utf8_to_wchar
762 = __conditional_t<
sizeof(wchar_t) ==
sizeof(
char32_t),
763 std::codecvt_utf8<wchar_t>,
764 std::codecvt_utf8_utf16<wchar_t>>;
768 struct __codecvt_utf8_to_utfNN :
std::codecvt<_CharT, char, mbstate_t>
773 using __codecvt_utf8_to_wide
774 = __conditional_t<is_same<_CharT, wchar_t>::value,
775 __codecvt_utf8_to_wchar,
776 __codecvt_utf8_to_utfNN>;
778#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
779#ifdef _GLIBCXX_USE_CHAR8_T
781 _S_wconvert(
const char8_t* __f,
const char8_t* __l,
const char8_t*)
783 const char* __f2 = (
const char*)__f;
784 const char* __l2 = (
const char*)__l;
786 std::codecvt_utf8_utf16<wchar_t> __wcvt;
787 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
793 _S_wconvert(
const char* __f,
const char* __l,
const char*)
795 using _Cvt = std::codecvt_utf8_utf16<wchar_t>;
796 const auto& __cvt = std::use_facet<_Cvt>(
std::locale{});
798 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
800 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
801 "Cannot convert character sequence",
802 std::make_error_code(errc::illegal_byte_sequence)));
806 _S_wconvert(
const _CharT* __f,
const _CharT* __l,
const void*)
808 __codecvt_utf8_to_wide __cvt;
810 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
812 const char* __f2 = __str.
data();
813 const char* __l2 = __f2 + __str.
size();
814 std::codecvt_utf8_utf16<wchar_t> __wcvt;
816 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
819 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
820 "Cannot convert character sequence",
821 std::make_error_code(errc::illegal_byte_sequence)));
825 _S_convert(
const _CharT* __f,
const _CharT* __l)
827 return _S_wconvert(__f, __l, (
const _CharT*)
nullptr);
831 _S_convert(
const _CharT* __f,
const _CharT* __l)
833#ifdef _GLIBCXX_USE_CHAR8_T
834 if constexpr (is_same<_CharT, char8_t>::value)
835 return string_type(__f, __l);
839 __codecvt_utf8_to_wide __cvt;
841 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
843 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
844 "Cannot convert character sequence",
845 std::make_error_code(errc::illegal_byte_sequence)));
851 _S_convert(_CharT* __f, _CharT* __l)
853 return _S_convert(
const_cast<const _CharT*
>(__f),
854 const_cast<const _CharT*
>(__l));
857 template<
typename _Iter>
859 _S_convert(_Iter __first, _Iter __last)
862 return _S_convert(__str.
data(), __str.
data() + __str.
size());
865 template<
typename _Iter,
typename _Cont>
867 _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
868 __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
869 {
return _S_convert(__first.base(), __last.base()); }
877 using difference_type = std::ptrdiff_t;
883 iterator() noexcept : _M_path(
nullptr), _M_cur(), _M_at_end() { }
894 {
auto __tmp = *
this; ++*
this;
return __tmp; }
899 {
auto __tmp = *
this; --*
this;
return __tmp; }
903 {
return __lhs._M_equals(__rhs); }
907 {
return !__lhs._M_equals(__rhs); }
912 iterator(
const path* __path, path::_List::const_iterator __iter) noexcept
913 : _M_path(__path), _M_cur(__iter), _M_at_end()
917 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
920 bool _M_equals(
iterator)
const noexcept;
923 path::_List::const_iterator _M_cur;
928 path::path() noexcept = default;
935 : _M_pathname(
std::
move(__p._M_pathname)),
936 _M_cmpts(__p._M_cmpts),
941 path::path(string_type&& __source)
942 : _M_pathname(
std::
move(__source))
943 { _M_split_cmpts(); }
946 path::path(string_type __str, _Type __type)
947 : _M_pathname(__str), _M_type(__type)
949 __glibcxx_assert(!empty());
950 __glibcxx_assert(_M_type != _Type::_Multi);
954 path::~path() =
default;
957 path::operator=(
const path& __p) =
default;
960 path::operator=(path&& __p)
noexcept
962 _M_pathname =
std::move(__p._M_pathname);
964 _M_type = __p._M_type;
970 path::operator=(string_type&& __source)
971 {
return *
this = path(
std::move(__source)); }
974 path::assign(string_type&& __source)
975 {
return *
this = path(
std::move(__source)); }
978 path::operator+=(
const path& __p)
980 return operator+=(__p.native());
984 path::operator+=(
const string_type& __x)
992 path::operator+=(
const value_type* __x)
1000 path::operator+=(value_type __x)
1007#if __cplusplus >= 201402L
1009 path::operator+=(basic_string_view<value_type> __x)
1011 _M_pathname.append(__x.data(), __x.size());
1017 template<
typename _CharT>
1018 inline __detail::_Path<_CharT*, _CharT*>&
1019 path::operator+=(_CharT __x)
1022 return concat(__addr, __addr + 1);
1026 path::make_preferred()
1028#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1029 std::replace(_M_pathname.begin(), _M_pathname.end(), L
'/',
1030 preferred_separator);
1035 inline void path::swap(path& __rhs)
noexcept
1037 _M_pathname.swap(__rhs._M_pathname);
1038 _M_cmpts.swap(__rhs._M_cmpts);
1042 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1046 if _GLIBCXX_CONSTEXPR (is_same<_CharT, value_type>::value)
1047 return { _M_pathname.
begin(), _M_pathname.end(), __a };
1049 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1051 const value_type* __first = _M_pathname.data();
1052 const value_type* __last = __first + _M_pathname.size();
1054#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1055 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1056 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1060 codecvt_utf8_utf16<value_type> __cvt;
1061 _String __u8str{_CharAlloc{__a}};
1062 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1067 operator()(
const _String& __from, _String&,
true_type)
1071 operator()(
const _String& __from, _WString& __to,
false_type)
1073#ifdef _GLIBCXX_USE_CHAR8_T
1074 if constexpr (is_same<_CharT, char8_t>::value)
1076 __to.assign(__from.begin(), __from.end());
1083 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1084 const char* __f = __from.data();
1085 const char* __l = __f + __from.size();
1086 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1092 _WString __wstr(__a);
1093 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1097#ifdef _GLIBCXX_USE_CHAR8_T
1098 if constexpr (is_same<_CharT, char8_t>::value)
1099 return _WString(__first, __last, __a);
1103 typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
1104 _WString __wstr(__a);
1105 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1109 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1110 "Cannot convert character sequence",
1111 std::make_error_code(errc::illegal_byte_sequence)));
1117#if _GLIBCXX_USE_WCHAR_T
1122#ifdef _GLIBCXX_USE_CHAR8_T
1123 inline std::u8string
1124 path::u8string()
const {
return string<char8_t>(); }
1127 path::u8string()
const
1129#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1132 std::codecvt_utf8_utf16<value_type> __cvt;
1133 const value_type* __first = _M_pathname.data();
1134 const value_type* __last = __first + _M_pathname.size();
1135 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1137 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1138 "Cannot convert character sequence",
1139 std::make_error_code(errc::illegal_byte_sequence)));
1152 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1154 path::generic_string(
const _Allocator& __a)
const
1156#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1157 const _CharT __slash = is_same<_CharT, wchar_t>::value
1161 const _CharT __slash = _CharT(
'/');
1163 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1164 __str.
reserve(_M_pathname.size());
1165 bool __add_slash =
false;
1166 for (
auto& __elem : *
this)
1168 if (__elem._M_type == _Type::_Root_dir)
1175 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1176 __add_slash = __elem._M_type == _Type::_Filename;
1182 path::generic_string()
const {
return generic_string<char>(); }
1184#if _GLIBCXX_USE_WCHAR_T
1186 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1189#ifdef _GLIBCXX_USE_CHAR8_T
1190 inline std::u8string
1191 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1194 path::generic_u8string()
const {
return generic_string<char>(); }
1198 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1201 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1204 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1207 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1209#if __cplusplus >= 201402L
1211 path::compare(basic_string_view<value_type> __s)
const
1212 {
return compare(path(__s)); }
1216 path::filename()
const {
return empty() ? path() : *--end(); }
1221 auto ext = _M_find_extension();
1222 if (ext.first && ext.second != 0)
1223 return path{ext.first->substr(0, ext.second)};
1228 path::extension()
const
1230 auto ext = _M_find_extension();
1232 return path{ext.first->substr(ext.second)};
1237 path::has_stem()
const
1239 auto ext = _M_find_extension();
1240 return ext.first && ext.second != 0;
1244 path::has_extension()
const
1246 auto ext = _M_find_extension();
1251 path::is_absolute()
const
1253#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1254 return has_root_name() && has_root_directory();
1256 return has_root_directory();
1260 inline path::iterator
1261 path::begin() const noexcept
1263 if (_M_type == _Type::_Multi)
1264 return iterator(
this, _M_cmpts.begin());
1265 return iterator(
this,
false);
1268 inline path::iterator
1269 path::end() const noexcept
1271 if (_M_type == _Type::_Multi)
1272 return iterator(
this, _M_cmpts.end());
1273 return iterator(
this,
true);
1276 inline path::iterator&
1277 path::iterator::operator++() noexcept
1279 __glibcxx_assert(_M_path !=
nullptr);
1280 if (_M_path->_M_type == _Type::_Multi)
1282 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1287 __glibcxx_assert(!_M_at_end);
1293 inline path::iterator&
1294 path::iterator::operator--() noexcept
1296 __glibcxx_assert(_M_path !=
nullptr);
1297 if (_M_path->_M_type == _Type::_Multi)
1299 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1304 __glibcxx_assert(_M_at_end);
1310 inline path::iterator::reference
1313 __glibcxx_assert(_M_path !=
nullptr);
1314 if (_M_path->_M_type == _Type::_Multi)
1316 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1323 path::iterator::_M_equals(iterator __rhs)
const noexcept
1325 if (_M_path != __rhs._M_path)
1327 if (_M_path ==
nullptr)
1329 if (_M_path->_M_type == path::_Type::_Multi)
1330 return _M_cur == __rhs._M_cur;
1331 return _M_at_end == __rhs._M_at_end;
1338 inline bool operator<(
const path& __lhs,
const path& __rhs)
noexcept
1339 {
return __lhs.compare(__rhs) < 0; }
1341 inline bool operator==(
const path& __lhs,
const path& __rhs)
noexcept
1342 {
return __lhs.compare(__rhs) == 0; }
1345_GLIBCXX_END_NAMESPACE_CXX11
1350_GLIBCXX_END_NAMESPACE_VERSION
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
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 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.
_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.
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.
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.