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 =
'/';
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());
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>
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() : _M_path(
nullptr), _M_cur(), _M_at_end() { }
876 iterator operator++(
int) {
auto __tmp = *
this; ++*
this;
return __tmp; }
879 iterator operator--(
int) {
auto __tmp = *
this; --*
this;
return __tmp; }
882 {
return __lhs._M_equals(__rhs); }
885 {
return !__lhs._M_equals(__rhs); }
890 iterator(
const path* __path, path::_List::const_iterator __iter)
891 : _M_path(__path), _M_cur(__iter), _M_at_end()
895 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
901 path::_List::const_iterator _M_cur;
907 path::operator=(
path&& __p)
noexcept
909 _M_pathname =
std::move(__p._M_pathname);
911 _M_type = __p._M_type;
917 path::operator=(string_type&& __source)
921 path::assign(string_type&& __source)
925 path::operator+=(
const path& __p)
927 return operator+=(__p.native());
931 path::operator+=(
const string_type& __x)
939 path::operator+=(
const value_type* __x)
947 path::operator+=(value_type __x)
954#if __cplusplus >= 201402L
956 path::operator+=(basic_string_view<value_type> __x)
958 _M_pathname.
append(__x.data(), __x.size());
964 template<
typename _CharT>
965 inline __detail::_Path<_CharT*, _CharT*>&
966 path::operator+=(_CharT __x)
969 return concat(__addr, __addr + 1);
973 path::make_preferred()
975#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
976 std::replace(_M_pathname.
begin(), _M_pathname.
end(), L
'/',
977 preferred_separator);
982 inline void path::swap(path& __rhs)
noexcept
984 _M_pathname.swap(__rhs._M_pathname);
985 _M_cmpts.swap(__rhs._M_cmpts);
989 template<
typename _CharT,
typename _Traits,
typename _Allocator>
991 path::string(
const _Allocator& __a)
const
993 if (is_same<_CharT, value_type>::value)
994 return { _M_pathname.
begin(), _M_pathname.
end(), __a };
996 using _WString = basic_string<_CharT, _Traits, _Allocator>;
998 const value_type* __first = _M_pathname.
data();
999 const value_type* __last = __first + _M_pathname.
size();
1001#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1002 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1003 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1007 codecvt_utf8_utf16<value_type> __cvt;
1008 _String __u8str{_CharAlloc{__a}};
1009 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1014 operator()(
const _String& __from, _String&,
true_type)
1018 operator()(
const _String& __from, _WString& __to,
false_type)
1020#ifdef _GLIBCXX_USE_CHAR8_T
1021 if constexpr (is_same<_CharT, char8_t>::value)
1023 __to.assign(__from.begin(), __from.end());
1030 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
1032 const char* __f = __from.data();
1033 const char* __l = __f + __from.size();
1034 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1040 _WString __wstr(__a);
1041 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1045#ifdef _GLIBCXX_USE_CHAR8_T
1046 if constexpr (is_same<_CharT, char8_t>::value)
1047 return _WString(__first, __last, __a);
1051 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
1052 _WString __wstr(__a);
1053 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1057 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1058 "Cannot convert character sequence",
1059 std::make_error_code(errc::illegal_byte_sequence)));
1063 path::string()
const {
return string<char>(); }
1065#if _GLIBCXX_USE_WCHAR_T
1067 path::wstring()
const {
return string<wchar_t>(); }
1070#ifdef _GLIBCXX_USE_CHAR8_T
1071 inline std::u8string
1072 path::u8string()
const {
return string<char8_t>(); }
1075 path::u8string()
const
1077#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1080 std::codecvt_utf8_utf16<value_type> __cvt;
1081 const value_type* __first = _M_pathname.
data();
1082 const value_type* __last = __first + _M_pathname.
size();
1083 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1085 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1086 "Cannot convert character sequence",
1087 std::make_error_code(errc::illegal_byte_sequence)));
1095 path::u16string()
const {
return string<char16_t>(); }
1098 path::u32string()
const {
return string<char32_t>(); }
1100 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1102 path::generic_string(
const _Allocator& __a)
const
1104#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1105 const _CharT __slash = is_same<_CharT, wchar_t>::value
1109 const _CharT __slash = _CharT(
'/');
1111 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1113 bool __add_slash =
false;
1114 for (
auto& __elem : *this)
1116 if (__elem._M_type == _Type::_Root_dir)
1123 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1124 __add_slash = __elem._M_type == _Type::_Filename;
1130 path::generic_string()
const {
return generic_string<char>(); }
1132#if _GLIBCXX_USE_WCHAR_T
1134 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1137#ifdef _GLIBCXX_USE_CHAR8_T
1138 inline std::u8string
1139 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1142 path::generic_u8string()
const {
return generic_string<char>(); }
1146 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1149 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1152 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1155 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1157#if __cplusplus >= 201402L
1159 path::compare(basic_string_view<value_type> __s)
const
1160 {
return compare(path(__s)); }
1164 path::filename()
const {
return empty() ? path() : *--end(); }
1169 auto ext = _M_find_extension();
1170 if (ext.first && ext.second != 0)
1171 return path{ext.first->substr(0, ext.second)};
1176 path::extension()
const
1178 auto ext = _M_find_extension();
1180 return path{ext.first->substr(ext.second)};
1185 path::has_stem()
const
1187 auto ext = _M_find_extension();
1188 return ext.first && ext.second != 0;
1192 path::has_extension()
const
1194 auto ext = _M_find_extension();
1199 path::is_absolute()
const
1201#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1202 return has_root_name() && has_root_directory();
1204 return has_root_directory();
1208 inline path::iterator
1211 if (_M_type == _Type::_Multi)
1212 return iterator(
this, _M_cmpts.
begin());
1213 return iterator(
this,
false);
1216 inline path::iterator
1219 if (_M_type == _Type::_Multi)
1220 return iterator(
this, _M_cmpts.
end());
1221 return iterator(
this,
true);
1224 inline path::iterator&
1225 path::iterator::operator++()
1227 __glibcxx_assert(_M_path !=
nullptr);
1228 if (_M_path->_M_type == _Type::_Multi)
1230 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.
end());
1235 __glibcxx_assert(!_M_at_end);
1241 inline path::iterator&
1242 path::iterator::operator--()
1244 __glibcxx_assert(_M_path !=
nullptr);
1245 if (_M_path->_M_type == _Type::_Multi)
1247 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1252 __glibcxx_assert(_M_at_end);
1258 inline path::iterator::reference
1259 path::iterator::operator*()
const
1261 __glibcxx_assert(_M_path !=
nullptr);
1262 if (_M_path->_M_type == _Type::_Multi)
1264 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1271 path::iterator::_M_equals(iterator __rhs)
const
1273 if (_M_path != __rhs._M_path)
1275 if (_M_path ==
nullptr)
1277 if (_M_path->_M_type == path::_Type::_Multi)
1278 return _M_cur == __rhs._M_cur;
1279 return _M_at_end == __rhs._M_at_end;
1286 inline bool operator<(
const path& __lhs,
const path& __rhs)
noexcept
1287 {
return __lhs.compare(__rhs) < 0; }
1289 inline bool operator==(
const path& __lhs,
const path& __rhs)
noexcept
1290 {
return __lhs.compare(__rhs) == 0; }
1293_GLIBCXX_END_NAMESPACE_CXX11
1298_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 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.
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.
basic_string & append(const basic_string &__str)
Append a string to this string.
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.
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.