30 #ifndef _GLIBCXX_EXPERIMENTAL_FS_PATH_H
31 #define _GLIBCXX_EXPERIMENTAL_FS_PATH_H 1
33 #if __cplusplus < 201103L
47 #if __cplusplus == 201402L
51 #if defined(_WIN32) && !defined(__CYGWIN__)
52 # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1
56 namespace std _GLIBCXX_VISIBILITY(default)
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 namespace experimental
66 _GLIBCXX_BEGIN_NAMESPACE_CXX11
68 #if __cplusplus == 201402L
70 #elif __cplusplus > 201402L
81 template<
typename _CharT,
82 typename _Ch =
typename remove_const<_CharT>::type>
83 using __is_encoded_char
84 = __or_<is_same<_Ch, char>,
85 is_same<_Ch, wchar_t>,
86 #ifdef _GLIBCXX_USE_CHAR8_T
87 is_same<_Ch, char8_t>,
89 is_same<_Ch, char16_t>,
90 is_same<_Ch, char32_t>>;
92 template<
typename _Iter,
94 using __is_path_iter_src
95 = __and_<__is_encoded_char<typename _Iter_traits::value_type>,
97 typename _Iter_traits::iterator_category>>;
99 template<
typename _Iter>
100 static __is_path_iter_src<_Iter>
101 __is_path_src(_Iter,
int);
103 template<
typename _CharT,
typename _Traits,
typename _Alloc>
104 static __is_encoded_char<_CharT>
105 __is_path_src(
const basic_string<_CharT, _Traits, _Alloc>&,
int);
107 #if __cplusplus >= 201402L
108 template<
typename _CharT,
typename _Traits>
109 static __is_encoded_char<_CharT>
110 __is_path_src(
const basic_string_view<_CharT, _Traits>&,
int);
113 template<
typename _Unknown>
115 __is_path_src(
const _Unknown&, ...);
117 template<
typename _Tp1,
typename _Tp2>
118 struct __constructible_from;
120 template<
typename _Iter>
121 struct __constructible_from<_Iter, _Iter>
122 : __is_path_iter_src<_Iter>
125 template<
typename _Source>
126 struct __constructible_from<_Source, void>
127 : decltype(__is_path_src(std::declval<const _Source&>(), 0))
130 template<
typename _Tp1,
typename _Tp2 = void,
131 typename _Tp1_nocv =
typename remove_cv<_Tp1>::type,
132 typename _Tp1_noptr =
typename remove_pointer<_Tp1>::type>
133 using _Path =
typename
135 __not_<is_void<_Tp1_noptr>>,
136 __constructible_from<_Tp1, _Tp2>>::value,
139 template<
typename _Source>
141 _S_range_begin(_Source __begin) {
return __begin; }
143 struct __nul_terminated { };
145 template<
typename _Source>
146 inline __nul_terminated
147 _S_range_end(_Source) {
return {}; }
149 template<
typename _CharT,
typename _Traits,
typename _Alloc>
151 _S_range_begin(
const basic_string<_CharT, _Traits, _Alloc>& __str)
152 {
return __str.data(); }
154 template<
typename _CharT,
typename _Traits,
typename _Alloc>
156 _S_range_end(
const basic_string<_CharT, _Traits, _Alloc>& __str)
157 {
return __str.data() + __str.size(); }
159 #if __cplusplus >= 201402L
160 template<
typename _CharT,
typename _Traits>
162 _S_range_begin(
const basic_string_view<_CharT, _Traits>& __str)
163 {
return __str.data(); }
165 template<
typename _CharT,
typename _Traits>
167 _S_range_end(
const basic_string_view<_CharT, _Traits>& __str)
168 {
return __str.data() + __str.size(); }
171 template<
typename _Tp,
172 typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
174 typename _UnqualVal =
typename std::remove_const<_Val>::type>
179 template<
typename _Tp,
180 typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
182 typename _UnqualVal =
typename std::remove_const<_Val>::type>
186 #ifdef _GLIBCXX_USE_CHAR8_T
189 >::value, _UnqualVal>::type;
204 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
205 typedef wchar_t value_type;
206 static constexpr value_type preferred_separator = L
'\\';
208 typedef char value_type;
209 static constexpr value_type preferred_separator =
'/';
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>
737 template<
typename _Iter>
739 _S_convert(_Iter __first, _Iter __last)
740 {
return string_type{__first, __last}; }
743 template<
typename _CharT>
746 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
747 #ifdef _GLIBCXX_USE_CHAR8_T
749 _S_wconvert(
const char8_t* __f,
const char8_t* __l,
const char8_t*)
751 const char* __f2 = (
const char*)__f;
752 const char* __l2 = (
const char*)__l;
754 std::codecvt_utf8_utf16<wchar_t> __wcvt;
755 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
761 _S_wconvert(
const char* __f,
const char* __l,
const char*)
764 const auto& __cvt = std::use_facet<_Cvt>(
std::locale{});
766 if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
768 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
769 "Cannot convert character sequence",
770 std::make_error_code(errc::illegal_byte_sequence)));
774 _S_wconvert(
const _CharT* __f,
const _CharT* __l,
const void*)
776 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
779 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
781 const char* __f2 = __str.
data();
782 const char* __l2 = __f2 + __str.
size();
783 std::codecvt_utf8_utf16<wchar_t> __wcvt;
785 if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
788 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
789 "Cannot convert character sequence",
790 std::make_error_code(errc::illegal_byte_sequence)));
794 _S_convert(
const _CharT* __f,
const _CharT* __l)
796 return _S_wconvert(__f, __l, (
const _CharT*)
nullptr);
800 _S_convert(
const _CharT* __f,
const _CharT* __l)
802 #ifdef _GLIBCXX_USE_CHAR8_T
803 if constexpr (is_same<_CharT, char8_t>::value)
804 return string_type(__f, __l);
808 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
811 if (__str_codecvt_out_all(__f, __l, __str, __cvt))
813 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
814 "Cannot convert character sequence",
815 std::make_error_code(errc::illegal_byte_sequence)));
821 _S_convert(_CharT* __f, _CharT* __l)
823 return _S_convert(
const_cast<const _CharT*
>(__f),
824 const_cast<const _CharT*
>(__l));
827 template<
typename _Iter>
829 _S_convert(_Iter __first, _Iter __last)
832 return _S_convert(__str.
data(), __str.
data() + __str.
size());
835 template<
typename _Iter,
typename _Cont>
837 _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
838 __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
839 {
return _S_convert(__first.base(), __last.base()); }
847 using difference_type = std::ptrdiff_t;
853 iterator() noexcept : _M_path(
nullptr), _M_cur(), _M_at_end() { }
864 {
auto __tmp = *
this; ++*
this;
return __tmp; }
869 {
auto __tmp = *
this; --*
this;
return __tmp; }
873 {
return __lhs._M_equals(__rhs); }
877 {
return !__lhs._M_equals(__rhs); }
882 iterator(
const path* __path, path::_List::const_iterator __iter) noexcept
883 : _M_path(__path), _M_cur(__iter), _M_at_end()
887 : _M_path(__path), _M_cur(), _M_at_end(__at_end)
890 bool _M_equals(
iterator)
const noexcept;
893 path::_List::const_iterator _M_cur;
898 path::path() noexcept = default;
905 : _M_pathname(
std::
move(__p._M_pathname)),
906 _M_cmpts(__p._M_cmpts),
911 path::path(string_type&& __source)
912 : _M_pathname(
std::
move(__source))
913 { _M_split_cmpts(); }
916 path::path(string_type __str, _Type __type)
917 : _M_pathname(__str), _M_type(__type)
919 __glibcxx_assert(!empty());
920 __glibcxx_assert(_M_type != _Type::_Multi);
924 path::~path() =
default;
927 path::operator=(
const path& __p) =
default;
930 path::operator=(path&& __p) noexcept
932 _M_pathname =
std::move(__p._M_pathname);
934 _M_type = __p._M_type;
940 path::operator=(string_type&& __source)
941 {
return *
this = path(
std::move(__source)); }
944 path::assign(string_type&& __source)
945 {
return *
this = path(
std::move(__source)); }
948 path::operator+=(
const path& __p)
950 return operator+=(__p.native());
954 path::operator+=(
const string_type& __x)
962 path::operator+=(
const value_type* __x)
970 path::operator+=(value_type __x)
977 #if __cplusplus >= 201402L
979 path::operator+=(basic_string_view<value_type> __x)
981 _M_pathname.append(__x.data(), __x.size());
987 template<
typename _CharT>
988 inline __detail::_Path<_CharT*, _CharT*>&
989 path::operator+=(_CharT __x)
992 return concat(__addr, __addr + 1);
996 path::make_preferred()
998 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
999 std::replace(_M_pathname.begin(), _M_pathname.end(), L
'/',
1000 preferred_separator);
1005 inline void path::swap(path& __rhs) noexcept
1007 _M_pathname.swap(__rhs._M_pathname);
1008 _M_cmpts.swap(__rhs._M_cmpts);
1012 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1016 if (is_same<_CharT, value_type>::value)
1017 return { _M_pathname.
begin(), _M_pathname.end(), __a };
1019 using _WString = basic_string<_CharT, _Traits, _Allocator>;
1021 const value_type* __first = _M_pathname.data();
1022 const value_type* __last = __first + _M_pathname.size();
1024 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1025 using _CharAlloc = __alloc_rebind<_Allocator, char>;
1026 using _String = basic_string<char, char_traits<char>, _CharAlloc>;
1030 codecvt_utf8_utf16<value_type> __cvt;
1031 _String __u8str{_CharAlloc{__a}};
1032 if (__str_codecvt_out_all(__first, __last, __u8str, __cvt))
1037 operator()(
const _String& __from, _String&,
true_type)
1041 operator()(
const _String& __from, _WString& __to,
false_type)
1043 #ifdef _GLIBCXX_USE_CHAR8_T
1044 if constexpr (is_same<_CharT, char8_t>::value)
1046 __to.assign(__from.begin(), __from.end());
1053 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t>
1055 const char* __f = __from.data();
1056 const char* __l = __f + __from.size();
1057 if (__str_codecvt_in_all(__f, __l, __to, __cvt))
1063 _WString __wstr(__a);
1064 if (
auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
1068 #ifdef _GLIBCXX_USE_CHAR8_T
1069 if constexpr (is_same<_CharT, char8_t>::value)
1070 return _WString(__first, __last, __a);
1074 struct _UCvt :
std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
1075 _WString __wstr(__a);
1076 if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
1080 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1081 "Cannot convert character sequence",
1082 std::make_error_code(errc::illegal_byte_sequence)));
1086 path::string()
const {
return string<char>(); }
1088 #if _GLIBCXX_USE_WCHAR_T
1090 path::wstring()
const {
return string<wchar_t>(); }
1093 #ifdef _GLIBCXX_USE_CHAR8_T
1094 inline std::u8string
1095 path::u8string()
const {
return string<char8_t>(); }
1098 path::u8string()
const
1100 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1103 std::codecvt_utf8_utf16<value_type> __cvt;
1104 const value_type* __first = _M_pathname.data();
1105 const value_type* __last = __first + _M_pathname.size();
1106 if (__str_codecvt_out_all(__first, __last, __str, __cvt))
1108 _GLIBCXX_THROW_OR_ABORT(filesystem_error(
1109 "Cannot convert character sequence",
1110 std::make_error_code(errc::illegal_byte_sequence)));
1118 path::u16string()
const {
return string<char16_t>(); }
1121 path::u32string()
const {
return string<char32_t>(); }
1123 template<
typename _CharT,
typename _Traits,
typename _Allocator>
1125 path::generic_string(
const _Allocator& __a)
const
1127 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1128 const _CharT __slash = is_same<_CharT, wchar_t>::value
1132 const _CharT __slash = _CharT(
'/');
1134 basic_string<_CharT, _Traits, _Allocator> __str(__a);
1135 __str.
reserve(_M_pathname.size());
1136 bool __add_slash =
false;
1137 for (
auto& __elem : *
this)
1139 if (__elem._M_type == _Type::_Root_dir)
1146 __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
1147 __add_slash = __elem._M_type == _Type::_Filename;
1153 path::generic_string()
const {
return generic_string<char>(); }
1155 #if _GLIBCXX_USE_WCHAR_T
1157 path::generic_wstring()
const {
return generic_string<wchar_t>(); }
1160 #ifdef _GLIBCXX_USE_CHAR8_T
1161 inline std::u8string
1162 path::generic_u8string()
const {
return generic_string<char8_t>(); }
1165 path::generic_u8string()
const {
return generic_string<char>(); }
1169 path::generic_u16string()
const {
return generic_string<char16_t>(); }
1172 path::generic_u32string()
const {
return generic_string<char32_t>(); }
1175 path::compare(
const string_type& __s)
const {
return compare(path(__s)); }
1178 path::compare(
const value_type* __s)
const {
return compare(path(__s)); }
1180 #if __cplusplus >= 201402L
1182 path::compare(basic_string_view<value_type> __s)
const
1183 {
return compare(path(__s)); }
1187 path::filename()
const {
return empty() ? path() : *--end(); }
1192 auto ext = _M_find_extension();
1193 if (ext.first && ext.second != 0)
1194 return path{ext.first->substr(0, ext.second)};
1199 path::extension()
const
1201 auto ext = _M_find_extension();
1203 return path{ext.first->substr(ext.second)};
1208 path::has_stem()
const
1210 auto ext = _M_find_extension();
1211 return ext.first && ext.second != 0;
1215 path::has_extension()
const
1217 auto ext = _M_find_extension();
1222 path::is_absolute()
const
1224 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
1225 return has_root_name() && has_root_directory();
1227 return has_root_directory();
1231 inline path::iterator
1232 path::begin() const noexcept
1234 if (_M_type == _Type::_Multi)
1235 return iterator(
this, _M_cmpts.begin());
1236 return iterator(
this,
false);
1239 inline path::iterator
1240 path::end() const noexcept
1242 if (_M_type == _Type::_Multi)
1243 return iterator(
this, _M_cmpts.end());
1244 return iterator(
this,
true);
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.end());
1258 __glibcxx_assert(!_M_at_end);
1264 inline path::iterator&
1265 path::iterator::operator--() noexcept
1267 __glibcxx_assert(_M_path !=
nullptr);
1268 if (_M_path->_M_type == _Type::_Multi)
1270 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
1275 __glibcxx_assert(_M_at_end);
1281 inline path::iterator::reference
1282 path::iterator::operator*() const noexcept
1284 __glibcxx_assert(_M_path !=
nullptr);
1285 if (_M_path->_M_type == _Type::_Multi)
1287 __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
1294 path::iterator::_M_equals(iterator __rhs)
const noexcept
1296 if (_M_path != __rhs._M_path)
1298 if (_M_path ==
nullptr)
1300 if (_M_path->_M_type == path::_Type::_Multi)
1301 return _M_cur == __rhs._M_cur;
1302 return _M_at_end == __rhs._M_at_end;
1309 inline bool operator<(
const path& __lhs,
const path& __rhs) noexcept
1310 {
return __lhs.compare(__rhs) < 0; }
1312 inline bool operator==(
const path& __lhs,
const path& __rhs) noexcept
1313 {
return __lhs.compare(__rhs) == 0; }
1316 _GLIBCXX_END_NAMESPACE_CXX11
1321 _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.
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.
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.