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 __null_terminated { };
145 template<
typename _Source>
146 inline __null_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::__null_terminated)
477 {
return string_type(__src); }
480 _S_convert(
const value_type* __src, __detail::__null_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::__null_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::__null_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>
751 template<
typename _Iter>
753 _S_convert(_Iter __first, _Iter __last)
754 {
return string_type{__first, __last}; }
757 template<
typename _CharT>
760 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
761 #ifdef _GLIBCXX_USE_CHAR8_T
763 _S_wconvert(
const char8_t* __f,
const char8_t* __l,
const char8_t*)
765 const char* __f2 = (
const char*)__f;
766 const char* __l2 = (
const char*)__l;
768 std::codecvt_utf8_utf16<wchar_t> __wcvt;
769 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
775 _S_wconvert(
const char* __f,
const char* __l,
const char*)
778 const auto& __cvt = std::use_facet<_Cvt>(
std::locale{});
780 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
782 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
783 "Cannot convert character sequence",
784 std::make_error_code(errc::illegal_byte_sequence)));
788 _S_wconvert(
const _CharT* __f,
const _CharT* __l,
const void*)
790 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
793 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
795 const char* __f2 = __str.
data();
796 const char* __l2 = __f2 + __str.
size();
797 std::codecvt_utf8_utf16<wchar_t> __wcvt;
799 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
802 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
803 "Cannot convert character sequence",
804 std::make_error_code(errc::illegal_byte_sequence)));
808 _S_convert(
const _CharT* __f,
const _CharT* __l)
810 return _S_wconvert(__f, __l, (
const _CharT*)
nullptr);
814 _S_convert(
const _CharT* __f,
const _CharT* __l)
816 #ifdef _GLIBCXX_USE_CHAR8_T
817 if constexpr (is_same<_CharT, char8_t>::value)
818 return string_type(__f, __l);
822 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
825 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
827 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
828 "Cannot convert character sequence",
829 std::make_error_code(errc::illegal_byte_sequence)));
835 _S_convert(_CharT* __f, _CharT* __l)
837 return _S_convert(
const_cast<const _CharT*
>(__f),
838 const_cast<const _CharT*
>(__l));
841 template<
typename _Iter>
843 _S_convert(_Iter __first, _Iter __last)
846 return _S_convert(__str.
data(), __str.
data() + __str.
size());
849 template<
typename _Iter,
typename _Cont>
851 _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
852 __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
853 {
return _S_convert(__first.base(), __last.base()); }
861 using difference_type = std::ptrdiff_t;
867 iterator() noexcept : _M_path(
nullptr), _M_cur(), _M_at_end() { }
878 {
auto __tmp = *
this; ++*
this;
return __tmp; }
883 {
auto __tmp = *
this; --*
this;
return __tmp; }
887 {
return __lhs._M_equals(__rhs); }
891 {
return !__lhs._M_equals(__rhs); }
896 iterator(
const path* __path, path::_List::const_iterator __iter) noexcept
897 : _M_path(__path), _M_cur(__iter), _M_at_end()
901 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
904 bool _M_equals(
iterator)
const noexcept;
907 path::_List::const_iterator _M_cur;
913 path::operator=(
path&& __p) noexcept
915 _M_pathname =
std::move(__p._M_pathname);
917 _M_type = __p._M_type;
923 path::operator=(string_type&& __source)
927 path::assign(string_type&& __source)
931 path::operator+=(
const path& __p)
933 return operator+=(__p.native());
937 path::operator+=(
const string_type& __x)
945 path::operator+=(
const value_type* __x)
953 path::operator+=(value_type __x)
960 #if __cplusplus >= 201402L
962 path::operator+=(basic_string_view<value_type> __x)
964 _M_pathname.
append(__x.data(), __x.size());
970 template<
typename _CharT>
971 inline __detail::_Path<_CharT*, _CharT*>&
972 path::operator+=(_CharT __x)
975 return concat(__addr, __addr + 1);
979 path::make_preferred()
981 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
982 std::replace(_M_pathname.
begin(), _M_pathname.
end(), L
'/',
983 preferred_separator);
988 inline void path::swap(path& __rhs) noexcept
990 _M_pathname.swap(__rhs._M_pathname);
991 _M_cmpts.swap(__rhs._M_cmpts);
995 template<
typename _CharT,
typename _Traits,
typename _Allocator>
999 if (is_same<_CharT, value_type>::value)
1000 return { _M_pathname.
begin(), _M_pathname.
end(), __a };
1002 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1004 const value_type* __first = _M_pathname.
data();
1005 const value_type* __last = __first + _M_pathname.
size();
1007 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1008 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1009 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1013 codecvt_utf8_utf16<value_type> __cvt;
1014 _String __u8str{_CharAlloc{__a}};
1015 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1020 operator()(
const _String& __from, _String&,
true_type)
1024 operator()(
const _String& __from, _WString& __to,
false_type)
1026 #ifdef _GLIBCXX_USE_CHAR8_T
1027 if constexpr (is_same<_CharT, char8_t>::value)
1029 __to.assign(__from.begin(), __from.end());
1036 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
1038 const char* __f = __from.data();
1039 const char* __l = __f + __from.size();
1040 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1046 _WString __wstr(__a);
1047 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1051 #ifdef _GLIBCXX_USE_CHAR8_T
1052 if constexpr (is_same<_CharT, char8_t>::value)
1053 return _WString(__first, __last, __a);
1057 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
1058 _WString __wstr(__a);
1059 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1063 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1064 "Cannot convert character sequence",
1065 std::make_error_code(errc::illegal_byte_sequence)));
1069 path::string()
const {
return string<char>(); }
1071 #if _GLIBCXX_USE_WCHAR_T
1073 path::wstring()
const {
return string<wchar_t>(); }
1076 #ifdef _GLIBCXX_USE_CHAR8_T
1077 inline std::u8string
1078 path::u8string()
const {
return string<char8_t>(); }
1081 path::u8string()
const
1083 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1086 std::codecvt_utf8_utf16<value_type> __cvt;
1087 const value_type* __first = _M_pathname.
data();
1088 const value_type* __last = __first + _M_pathname.
size();
1089 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1091 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1092 "Cannot convert character sequence",
1093 std::make_error_code(errc::illegal_byte_sequence)));
1101 path::u16string()
const {
return string<char16_t>(); }
1104 path::u32string()
const {
return string<char32_t>(); }
1106 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1108 path::generic_string(
const _Allocator& __a)
const
1110 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1111 const _CharT __slash = is_same<_CharT, wchar_t>::value
1115 const _CharT __slash = _CharT(
'/');
1117 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1119 bool __add_slash =
false;
1120 for (
auto& __elem : *
this)
1122 if (__elem._M_type == _Type::_Root_dir)
1129 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1130 __add_slash = __elem._M_type == _Type::_Filename;
1136 path::generic_string()
const {
return generic_string<char>(); }
1138 #if _GLIBCXX_USE_WCHAR_T
1140 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1143 #ifdef _GLIBCXX_USE_CHAR8_T
1144 inline std::u8string
1145 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1148 path::generic_u8string()
const {
return generic_string<char>(); }
1152 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1155 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1158 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1161 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1163 #if __cplusplus >= 201402L
1165 path::compare(basic_string_view<value_type> __s)
const
1166 {
return compare(path(__s)); }
1170 path::filename()
const {
return empty() ? path() : *--end(); }
1175 auto ext = _M_find_extension();
1176 if (ext.first && ext.second != 0)
1177 return path{ext.first->substr(0, ext.second)};
1182 path::extension()
const
1184 auto ext = _M_find_extension();
1186 return path{ext.first->substr(ext.second)};
1191 path::has_stem()
const
1193 auto ext = _M_find_extension();
1194 return ext.first && ext.second != 0;
1198 path::has_extension()
const
1200 auto ext = _M_find_extension();
1205 path::is_absolute()
const
1207 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1208 return has_root_name() && has_root_directory();
1210 return has_root_directory();
1214 inline path::iterator
1215 path::begin() const noexcept
1217 if (_M_type == _Type::_Multi)
1218 return iterator(
this, _M_cmpts.
begin());
1219 return iterator(
this,
false);
1222 inline path::iterator
1223 path::end() const noexcept
1225 if (_M_type == _Type::_Multi)
1226 return iterator(
this, _M_cmpts.
end());
1227 return iterator(
this,
true);
1230 inline path::iterator&
1231 path::iterator::operator++() noexcept
1233 __glibcxx_assert(_M_path !=
nullptr);
1234 if (_M_path->_M_type == _Type::_Multi)
1236 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.
end());
1241 __glibcxx_assert(!_M_at_end);
1247 inline path::iterator&
1248 path::iterator::operator--() noexcept
1250 __glibcxx_assert(_M_path !=
nullptr);
1251 if (_M_path->_M_type == _Type::_Multi)
1253 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1258 __glibcxx_assert(_M_at_end);
1264 inline path::iterator::reference
1265 path::iterator::operator*() const noexcept
1267 __glibcxx_assert(_M_path !=
nullptr);
1268 if (_M_path->_M_type == _Type::_Multi)
1270 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1277 path::iterator::_M_equals(iterator __rhs)
const noexcept
1279 if (_M_path != __rhs._M_path)
1281 if (_M_path ==
nullptr)
1283 if (_M_path->_M_type == path::_Type::_Multi)
1284 return _M_cur == __rhs._M_cur;
1285 return _M_at_end == __rhs._M_at_end;
1292 inline bool operator<(
const path& __lhs,
const path& __rhs) noexcept
1293 {
return __lhs.compare(__rhs) < 0; }
1295 inline bool operator==(
const path& __lhs,
const path& __rhs) noexcept
1296 {
return __lhs.compare(__rhs) == 0; }
1299 _GLIBCXX_END_NAMESPACE_CXX11
1304 _GLIBCXX_END_NAMESPACE_VERSION
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.
basic_string< char > string
A string of char.
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.
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.
Class codecvt<wchar_t, char, mbstate_t> specialization.
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.
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.
constexpr iterator end() noexcept
constexpr 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.