File indexing completed on 2026-05-03 08:13:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___FILESYSTEM_PATH_H
0011 #define _LIBCPP___CXX03___FILESYSTEM_PATH_H
0012
0013 #include <__cxx03/__algorithm/replace.h>
0014 #include <__cxx03/__algorithm/replace_copy.h>
0015 #include <__cxx03/__config>
0016 #include <__cxx03/__functional/unary_function.h>
0017 #include <__cxx03/__fwd/functional.h>
0018 #include <__cxx03/__iterator/back_insert_iterator.h>
0019 #include <__cxx03/__iterator/iterator_traits.h>
0020 #include <__cxx03/__type_traits/decay.h>
0021 #include <__cxx03/__type_traits/is_pointer.h>
0022 #include <__cxx03/__type_traits/remove_const.h>
0023 #include <__cxx03/__type_traits/remove_pointer.h>
0024 #include <__cxx03/cstddef>
0025 #include <__cxx03/string>
0026 #include <__cxx03/string_view>
0027
0028 #if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0029 # include <__cxx03/iomanip> // for quoted
0030 # include <__cxx03/locale>
0031 #endif
0032
0033 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0034 # pragma GCC system_header
0035 #endif
0036
0037 _LIBCPP_PUSH_MACROS
0038 #include <__cxx03/__undef_macros>
0039
0040 #if _LIBCPP_STD_VER >= 17
0041
0042 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
0043
0044 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
0045
0046 template <class _Tp>
0047 struct __can_convert_char {
0048 static const bool value = false;
0049 };
0050 template <class _Tp>
0051 struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
0052 template <>
0053 struct __can_convert_char<char> {
0054 static const bool value = true;
0055 using __char_type = char;
0056 };
0057 template <>
0058 struct __can_convert_char<wchar_t> {
0059 static const bool value = true;
0060 using __char_type = wchar_t;
0061 };
0062 # ifndef _LIBCPP_HAS_NO_CHAR8_T
0063 template <>
0064 struct __can_convert_char<char8_t> {
0065 static const bool value = true;
0066 using __char_type = char8_t;
0067 };
0068 # endif
0069 template <>
0070 struct __can_convert_char<char16_t> {
0071 static const bool value = true;
0072 using __char_type = char16_t;
0073 };
0074 template <>
0075 struct __can_convert_char<char32_t> {
0076 static const bool value = true;
0077 using __char_type = char32_t;
0078 };
0079
0080 template <class _ECharT, __enable_if_t<__can_convert_char<_ECharT>::value, int> = 0>
0081 _LIBCPP_HIDE_FROM_ABI bool __is_separator(_ECharT __e) {
0082 # if defined(_LIBCPP_WIN32API)
0083 return __e == _ECharT('/') || __e == _ECharT('\\');
0084 # else
0085 return __e == _ECharT('/');
0086 # endif
0087 }
0088
0089 # ifndef _LIBCPP_HAS_NO_CHAR8_T
0090 typedef u8string __u8_string;
0091 # else
0092 typedef string __u8_string;
0093 # endif
0094
0095 struct _NullSentinel {};
0096
0097 template <class _Tp>
0098 using _Void = void;
0099
0100 template <class _Tp, class = void>
0101 struct __is_pathable_string : public false_type {};
0102
0103 template <class _ECharT, class _Traits, class _Alloc>
0104 struct __is_pathable_string< basic_string<_ECharT, _Traits, _Alloc>,
0105 _Void<typename __can_convert_char<_ECharT>::__char_type> >
0106 : public __can_convert_char<_ECharT> {
0107 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
0108
0109 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
0110
0111 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
0112
0113 _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; }
0114 };
0115
0116 template <class _ECharT, class _Traits>
0117 struct __is_pathable_string< basic_string_view<_ECharT, _Traits>,
0118 _Void<typename __can_convert_char<_ECharT>::__char_type> >
0119 : public __can_convert_char<_ECharT> {
0120 using _Str = basic_string_view<_ECharT, _Traits>;
0121
0122 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
0123
0124 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
0125
0126 _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; }
0127 };
0128
0129 template <class _Source,
0130 class _DS = __decay_t<_Source>,
0131 class _UnqualPtrType = __remove_const_t<__remove_pointer_t<_DS> >,
0132 bool _IsCharPtr = is_pointer<_DS>::value && __can_convert_char<_UnqualPtrType>::value>
0133 struct __is_pathable_char_array : false_type {};
0134
0135 template <class _Source, class _ECharT, class _UPtr>
0136 struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> : __can_convert_char<__remove_const_t<_ECharT> > {
0137 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
0138
0139 _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(const _ECharT* __b) {
0140 using _Iter = const _ECharT*;
0141 const _ECharT __sentinel = _ECharT{};
0142 _Iter __e = __b;
0143 for (; *__e != __sentinel; ++__e)
0144 ;
0145 return __e;
0146 }
0147
0148 _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
0149 };
0150
0151 template <class _Iter, bool _IsIt = __has_input_iterator_category<_Iter>::value, class = void>
0152 struct __is_pathable_iter : false_type {};
0153
0154 template <class _Iter>
0155 struct __is_pathable_iter<
0156 _Iter,
0157 true,
0158 _Void<typename __can_convert_char< typename iterator_traits<_Iter>::value_type>::__char_type> >
0159 : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
0160 using _ECharT = typename iterator_traits<_Iter>::value_type;
0161
0162 _LIBCPP_HIDE_FROM_ABI static _Iter __range_begin(_Iter __b) { return __b; }
0163
0164 _LIBCPP_HIDE_FROM_ABI static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; }
0165
0166 _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Iter __b) { return *__b; }
0167 };
0168
0169 template <class _Tp,
0170 bool _IsStringT = __is_pathable_string<_Tp>::value,
0171 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
0172 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
0173 struct __is_pathable : false_type {
0174 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
0175 };
0176
0177 template <class _Tp>
0178 struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
0179
0180 template <class _Tp>
0181 struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
0182
0183 template <class _Tp>
0184 struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
0185
0186 # if defined(_LIBCPP_WIN32API)
0187 typedef wstring __path_string;
0188 typedef wchar_t __path_value;
0189 # else
0190 typedef string __path_string;
0191 typedef char __path_value;
0192 # endif
0193
0194 # if defined(_LIBCPP_WIN32API)
0195 _LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t);
0196 _LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t);
0197 # endif
0198
0199 template <class _ECharT>
0200 struct _PathCVT;
0201
0202 # if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0203 template <class _ECharT>
0204 struct _PathCVT {
0205 static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
0206
0207 typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
0208 # if defined(_LIBCPP_WIN32API)
0209 typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
0210 # endif
0211
0212 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _ECharT const* __b, _ECharT const* __e) {
0213 # if defined(_LIBCPP_WIN32API)
0214 string __utf8;
0215 _Narrower()(back_inserter(__utf8), __b, __e);
0216 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
0217 # else
0218 _Narrower()(back_inserter(__dest), __b, __e);
0219 # endif
0220 }
0221
0222 template <class _Iter>
0223 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
0224 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
0225 if (__b == __e)
0226 return;
0227 basic_string<_ECharT> __tmp(__b, __e);
0228 # if defined(_LIBCPP_WIN32API)
0229 string __utf8;
0230 _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length());
0231 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
0232 # else
0233 _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length());
0234 # endif
0235 }
0236
0237 template <class _Iter>
0238 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
0239 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
0240 const _ECharT __sentinel = _ECharT{};
0241 if (*__b == __sentinel)
0242 return;
0243 basic_string<_ECharT> __tmp;
0244 for (; *__b != __sentinel; ++__b)
0245 __tmp.push_back(*__b);
0246 # if defined(_LIBCPP_WIN32API)
0247 string __utf8;
0248 _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length());
0249 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
0250 # else
0251 _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length());
0252 # endif
0253 }
0254
0255 template <class _Source>
0256 _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) {
0257 using _Traits = __is_pathable<_Source>;
0258 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
0259 }
0260 };
0261 # endif
0262
0263 template <>
0264 struct _PathCVT<__path_value> {
0265 template <class _Iter, __enable_if_t<__has_exactly_input_iterator_category<_Iter>::value, int> = 0>
0266 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
0267 for (; __b != __e; ++__b)
0268 __dest.push_back(*__b);
0269 }
0270
0271 template <class _Iter, __enable_if_t<__has_forward_iterator_category<_Iter>::value, int> = 0>
0272 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
0273 __dest.append(__b, __e);
0274 }
0275
0276 template <class _Iter>
0277 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
0278 const char __sentinel = char{};
0279 for (; *__b != __sentinel; ++__b)
0280 __dest.push_back(*__b);
0281 }
0282
0283 template <class _Source>
0284 _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) {
0285 using _Traits = __is_pathable<_Source>;
0286 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
0287 }
0288 };
0289
0290 # if defined(_LIBCPP_WIN32API)
0291 template <>
0292 struct _PathCVT<char> {
0293 _LIBCPP_HIDE_FROM_ABI static void __append_string(__path_string& __dest, const basic_string<char>& __str) {
0294 size_t __size = __char_to_wide(__str, nullptr, 0);
0295 size_t __pos = __dest.size();
0296 __dest.resize(__pos + __size);
0297 __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size);
0298 }
0299
0300 template <class _Iter, __enable_if_t<__has_exactly_input_iterator_category<_Iter>::value, int> = 0>
0301 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
0302 basic_string<char> __tmp(__b, __e);
0303 __append_string(__dest, __tmp);
0304 }
0305
0306 template <class _Iter, __enable_if_t<__has_forward_iterator_category<_Iter>::value, int> = 0>
0307 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
0308 basic_string<char> __tmp(__b, __e);
0309 __append_string(__dest, __tmp);
0310 }
0311
0312 template <class _Iter>
0313 _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
0314 const char __sentinel = char{};
0315 basic_string<char> __tmp;
0316 for (; *__b != __sentinel; ++__b)
0317 __tmp.push_back(*__b);
0318 __append_string(__dest, __tmp);
0319 }
0320
0321 template <class _Source>
0322 _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) {
0323 using _Traits = __is_pathable<_Source>;
0324 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
0325 }
0326 };
0327
0328 template <class _ECharT>
0329 struct _PathExport {
0330 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
0331 typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
0332
0333 template <class _Str>
0334 _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) {
0335 string __utf8;
0336 _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
0337 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
0338 }
0339 };
0340
0341 template <>
0342 struct _PathExport<char> {
0343 template <class _Str>
0344 _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) {
0345 size_t __size = __wide_to_char(__src, nullptr, 0);
0346 size_t __pos = __dest.size();
0347 __dest.resize(__size);
0348 __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size);
0349 }
0350 };
0351
0352 template <>
0353 struct _PathExport<wchar_t> {
0354 template <class _Str>
0355 _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) {
0356 __dest.append(__src.begin(), __src.end());
0357 }
0358 };
0359
0360 template <>
0361 struct _PathExport<char16_t> {
0362 template <class _Str>
0363 _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) {
0364 __dest.append(__src.begin(), __src.end());
0365 }
0366 };
0367
0368 # ifndef _LIBCPP_HAS_NO_CHAR8_T
0369 template <>
0370 struct _PathExport<char8_t> {
0371 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
0372
0373 template <class _Str>
0374 _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) {
0375 _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
0376 }
0377 };
0378 # endif
0379 # endif
0380
0381 class _LIBCPP_EXPORTED_FROM_ABI path {
0382 template <class _SourceOrIter, class _Tp = path&>
0383 using _EnableIfPathable = __enable_if_t<__is_pathable<_SourceOrIter>::value, _Tp>;
0384
0385 template <class _Tp>
0386 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
0387
0388 template <class _Tp>
0389 using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
0390
0391 public:
0392 # if defined(_LIBCPP_WIN32API)
0393 typedef wchar_t value_type;
0394 static constexpr value_type preferred_separator = L'\\';
0395 # else
0396 typedef char value_type;
0397 static constexpr value_type preferred_separator = '/';
0398 # endif
0399 typedef basic_string<value_type> string_type;
0400 typedef basic_string_view<value_type> __string_view;
0401
0402 enum format : unsigned char { auto_format, native_format, generic_format };
0403
0404
0405 _LIBCPP_HIDE_FROM_ABI path() noexcept {}
0406 _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {}
0407 _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept : __pn_(std::move(__p.__pn_)) {}
0408
0409 _LIBCPP_HIDE_FROM_ABI path(string_type&& __s, format = format::auto_format) noexcept : __pn_(std::move(__s)) {}
0410
0411 template <class _Source, class = _EnableIfPathable<_Source, void> >
0412 _LIBCPP_HIDE_FROM_ABI path(const _Source& __src, format = format::auto_format) {
0413 _SourceCVT<_Source>::__append_source(__pn_, __src);
0414 }
0415
0416 template <class _InputIt>
0417 _LIBCPP_HIDE_FROM_ABI path(_InputIt __first, _InputIt __last, format = format::auto_format) {
0418 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
0419 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 _LIBCPP_HIDE_FROM_ABI ~path() = default;
0434
0435
0436 _LIBCPP_HIDE_FROM_ABI path& operator=(const path& __p) {
0437 __pn_ = __p.__pn_;
0438 return *this;
0439 }
0440
0441 _LIBCPP_HIDE_FROM_ABI path& operator=(path&& __p) noexcept {
0442 __pn_ = std::move(__p.__pn_);
0443 return *this;
0444 }
0445
0446 _LIBCPP_HIDE_FROM_ABI path& operator=(string_type&& __s) noexcept {
0447 __pn_ = std::move(__s);
0448 return *this;
0449 }
0450
0451 _LIBCPP_HIDE_FROM_ABI path& assign(string_type&& __s) noexcept {
0452 __pn_ = std::move(__s);
0453 return *this;
0454 }
0455
0456 template <class _Source>
0457 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator=(const _Source& __src) {
0458 return this->assign(__src);
0459 }
0460
0461 template <class _Source>
0462 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> assign(const _Source& __src) {
0463 __pn_.clear();
0464 _SourceCVT<_Source>::__append_source(__pn_, __src);
0465 return *this;
0466 }
0467
0468 template <class _InputIt>
0469 _LIBCPP_HIDE_FROM_ABI path& assign(_InputIt __first, _InputIt __last) {
0470 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
0471 __pn_.clear();
0472 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
0473 return *this;
0474 }
0475
0476 public:
0477
0478 # if defined(_LIBCPP_WIN32API)
0479 _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) {
0480 auto __p_root_name = __p.__root_name();
0481 auto __p_root_name_size = __p_root_name.size();
0482 if (__p.is_absolute() || (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) {
0483 __pn_ = __p.__pn_;
0484 return *this;
0485 }
0486 if (__p.has_root_directory()) {
0487 path __root_name_str = root_name();
0488 __pn_ = __root_name_str.native();
0489 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
0490 return *this;
0491 }
0492 if (has_filename() || (!has_root_directory() && is_absolute()))
0493 __pn_ += preferred_separator;
0494 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
0495 return *this;
0496 }
0497 template <class _Source>
0498 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) {
0499 return operator/=(path(__src));
0500 }
0501
0502 template <class _Source>
0503 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) {
0504 return operator/=(path(__src));
0505 }
0506
0507 template <class _InputIt>
0508 _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) {
0509 return operator/=(path(__first, __last));
0510 }
0511 # else
0512 _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) {
0513 if (__p.is_absolute()) {
0514 __pn_ = __p.__pn_;
0515 return *this;
0516 }
0517 if (has_filename())
0518 __pn_ += preferred_separator;
0519 __pn_ += __p.native();
0520 return *this;
0521 }
0522
0523
0524
0525
0526 template <class _Source>
0527 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) {
0528 return this->append(__src);
0529 }
0530
0531 template <class _Source>
0532 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) {
0533 using _Traits = __is_pathable<_Source>;
0534 using _CVT = _PathCVT<_SourceChar<_Source> >;
0535 bool __source_is_absolute = filesystem::__is_separator(_Traits::__first_or_null(__src));
0536 if (__source_is_absolute)
0537 __pn_.clear();
0538 else if (has_filename())
0539 __pn_ += preferred_separator;
0540 _CVT::__append_source(__pn_, __src);
0541 return *this;
0542 }
0543
0544 template <class _InputIt>
0545 _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) {
0546 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
0547 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
0548 using _CVT = _PathCVT<_ItVal>;
0549 if (__first != __last && filesystem::__is_separator(*__first))
0550 __pn_.clear();
0551 else if (has_filename())
0552 __pn_ += preferred_separator;
0553 _CVT::__append_range(__pn_, __first, __last);
0554 return *this;
0555 }
0556 # endif
0557
0558
0559 _LIBCPP_HIDE_FROM_ABI path& operator+=(const path& __x) {
0560 __pn_ += __x.__pn_;
0561 return *this;
0562 }
0563
0564 _LIBCPP_HIDE_FROM_ABI path& operator+=(const string_type& __x) {
0565 __pn_ += __x;
0566 return *this;
0567 }
0568
0569 _LIBCPP_HIDE_FROM_ABI path& operator+=(__string_view __x) {
0570 __pn_ += __x;
0571 return *this;
0572 }
0573
0574 _LIBCPP_HIDE_FROM_ABI path& operator+=(const value_type* __x) {
0575 __pn_ += __x;
0576 return *this;
0577 }
0578
0579 _LIBCPP_HIDE_FROM_ABI path& operator+=(value_type __x) {
0580 __pn_ += __x;
0581 return *this;
0582 }
0583
0584 template <class _ECharT, __enable_if_t<__can_convert_char<_ECharT>::value, int> = 0>
0585 _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) {
0586 _PathCVT<_ECharT>::__append_source(__pn_, basic_string_view<_ECharT>(&__x, 1));
0587 return *this;
0588 }
0589
0590 template <class _Source>
0591 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator+=(const _Source& __x) {
0592 return this->concat(__x);
0593 }
0594
0595 template <class _Source>
0596 _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> concat(const _Source& __x) {
0597 _SourceCVT<_Source>::__append_source(__pn_, __x);
0598 return *this;
0599 }
0600
0601 template <class _InputIt>
0602 _LIBCPP_HIDE_FROM_ABI path& concat(_InputIt __first, _InputIt __last) {
0603 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
0604 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
0605 return *this;
0606 }
0607
0608
0609 _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __pn_.clear(); }
0610
0611 _LIBCPP_HIDE_FROM_ABI path& make_preferred() {
0612 # if defined(_LIBCPP_WIN32API)
0613 std::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
0614 # endif
0615 return *this;
0616 }
0617
0618 _LIBCPP_HIDE_FROM_ABI path& remove_filename() {
0619 auto __fname = __filename();
0620 if (!__fname.empty())
0621 __pn_.erase(__fname.data() - __pn_.data());
0622 return *this;
0623 }
0624
0625 _LIBCPP_HIDE_FROM_ABI path& replace_filename(const path& __replacement) {
0626 remove_filename();
0627 return (*this /= __replacement);
0628 }
0629
0630 path& replace_extension(const path& __replacement = path());
0631
0632 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& __rhs) noexcept {
0633 return __lhs.__compare(__rhs.__pn_) == 0;
0634 }
0635 # if _LIBCPP_STD_VER <= 17
0636 friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const path& __lhs, const path& __rhs) noexcept {
0637 return __lhs.__compare(__rhs.__pn_) != 0;
0638 }
0639 friend _LIBCPP_HIDE_FROM_ABI bool operator<(const path& __lhs, const path& __rhs) noexcept {
0640 return __lhs.__compare(__rhs.__pn_) < 0;
0641 }
0642 friend _LIBCPP_HIDE_FROM_ABI bool operator<=(const path& __lhs, const path& __rhs) noexcept {
0643 return __lhs.__compare(__rhs.__pn_) <= 0;
0644 }
0645 friend _LIBCPP_HIDE_FROM_ABI bool operator>(const path& __lhs, const path& __rhs) noexcept {
0646 return __lhs.__compare(__rhs.__pn_) > 0;
0647 }
0648 friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept {
0649 return __lhs.__compare(__rhs.__pn_) >= 0;
0650 }
0651 # else
0652 friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept {
0653 return __lhs.__compare(__rhs.__pn_) <=> 0;
0654 }
0655 # endif
0656
0657 friend _LIBCPP_HIDE_FROM_ABI path operator/(const path& __lhs, const path& __rhs) {
0658 path __result(__lhs);
0659 __result /= __rhs;
0660 return __result;
0661 }
0662
0663 _LIBCPP_HIDE_FROM_ABI void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
0664
0665
0666 _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __s) { __pn_.reserve(__s); }
0667
0668
0669 _LIBCPP_HIDE_FROM_ABI const string_type& native() const noexcept { return __pn_; }
0670
0671 _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept { return __pn_.c_str(); }
0672
0673 _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; }
0674
0675 # if defined(_LIBCPP_WIN32API)
0676 _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return __pn_; }
0677
0678 _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const {
0679 std::wstring __s;
0680 __s.resize(__pn_.size());
0681 std::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
0682 return __s;
0683 }
0684
0685 # if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0686 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
0687 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const {
0688 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
0689 _Str __s(__a);
0690 __s.reserve(__pn_.size());
0691 _PathExport<_ECharT>::__append(__s, __pn_);
0692 return __s;
0693 }
0694
0695 _LIBCPP_HIDE_FROM_ABI std::string string() const { return string<char>(); }
0696 _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const {
0697 using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
0698 __u8_string __s;
0699 __s.reserve(__pn_.size());
0700 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
0701 return __s;
0702 }
0703
0704 _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
0705 _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
0706
0707
0708 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
0709 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
0710 generic_string(const _Allocator& __a = _Allocator()) const {
0711 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
0712 _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
0713
0714
0715
0716 std::replace(__s.begin(), __s.end(), static_cast<_ECharT>('\\'), static_cast<_ECharT>('/'));
0717 return __s;
0718 }
0719
0720 _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return generic_string<char>(); }
0721 _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return generic_string<char16_t>(); }
0722 _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return generic_string<char32_t>(); }
0723 _LIBCPP_HIDE_FROM_ABI __u8_string generic_u8string() const {
0724 __u8_string __s = u8string();
0725 std::replace(__s.begin(), __s.end(), '\\', '/');
0726 return __s;
0727 }
0728 # endif
0729 # else
0730
0731 _LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; }
0732 # ifndef _LIBCPP_HAS_NO_CHAR8_T
0733 _LIBCPP_HIDE_FROM_ABI std::u8string u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); }
0734 # else
0735 _LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; }
0736 # endif
0737
0738 # if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0739 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
0740 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const {
0741 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
0742 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
0743 _Str __s(__a);
0744 __s.reserve(__pn_.size());
0745 _CVT()(std::back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
0746 return __s;
0747 }
0748
0749 # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
0750 _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return string<wchar_t>(); }
0751 # endif
0752 _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
0753 _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
0754 # endif
0755
0756
0757 _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; }
0758 # ifndef _LIBCPP_HAS_NO_CHAR8_T
0759 _LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); }
0760 # else
0761 _LIBCPP_HIDE_FROM_ABI std::string generic_u8string() const { return __pn_; }
0762 # endif
0763
0764 # if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0765 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
0766 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
0767 generic_string(const _Allocator& __a = _Allocator()) const {
0768 return string<_ECharT, _Traits, _Allocator>(__a);
0769 }
0770
0771 # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
0772 _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { return string<wchar_t>(); }
0773 # endif
0774 _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return string<char16_t>(); }
0775 _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return string<char32_t>(); }
0776 # endif
0777 # endif
0778
0779 private:
0780 int __compare(__string_view) const;
0781 __string_view __root_name() const;
0782 __string_view __root_directory() const;
0783 __string_view __root_path_raw() const;
0784 __string_view __relative_path() const;
0785 __string_view __parent_path() const;
0786 __string_view __filename() const;
0787 __string_view __stem() const;
0788 __string_view __extension() const;
0789
0790 public:
0791
0792 _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { return __compare(__p.__pn_); }
0793 _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return __compare(__s); }
0794 _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { return __compare(__s); }
0795 _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return __compare(__s); }
0796
0797
0798 _LIBCPP_HIDE_FROM_ABI path root_name() const { return string_type(__root_name()); }
0799 _LIBCPP_HIDE_FROM_ABI path root_directory() const { return string_type(__root_directory()); }
0800 _LIBCPP_HIDE_FROM_ABI path root_path() const {
0801 # if defined(_LIBCPP_WIN32API)
0802 return string_type(__root_path_raw());
0803 # else
0804 return root_name().append(string_type(__root_directory()));
0805 # endif
0806 }
0807 _LIBCPP_HIDE_FROM_ABI path relative_path() const { return string_type(__relative_path()); }
0808 _LIBCPP_HIDE_FROM_ABI path parent_path() const { return string_type(__parent_path()); }
0809 _LIBCPP_HIDE_FROM_ABI path filename() const { return string_type(__filename()); }
0810 _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); }
0811 _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); }
0812
0813
0814 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); }
0815
0816 _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); }
0817 _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); }
0818 _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { return !__root_path_raw().empty(); }
0819 _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { return !__relative_path().empty(); }
0820 _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { return !__parent_path().empty(); }
0821 _LIBCPP_HIDE_FROM_ABI bool has_filename() const { return !__filename().empty(); }
0822 _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); }
0823 _LIBCPP_HIDE_FROM_ABI bool has_extension() const { return !__extension().empty(); }
0824
0825 _LIBCPP_HIDE_FROM_ABI bool is_absolute() const {
0826 # if defined(_LIBCPP_WIN32API)
0827 __string_view __root_name_str = __root_name();
0828 __string_view __root_dir = __root_directory();
0829 if (__root_name_str.size() == 2 && __root_name_str[1] == ':') {
0830
0831 return !__root_dir.empty();
0832 }
0833
0834 if (__root_name_str.empty())
0835 return false;
0836 if (__root_name_str.size() < 3)
0837 return false;
0838
0839 if (__root_name_str[0] != '/' && __root_name_str[0] != '\\')
0840 return false;
0841 if (__root_name_str[1] != '/' && __root_name_str[1] != '\\')
0842 return false;
0843
0844 return true;
0845 # else
0846 return has_root_directory();
0847 # endif
0848 }
0849 _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); }
0850
0851
0852 path lexically_normal() const;
0853 path lexically_relative(const path& __base) const;
0854
0855 _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const {
0856 path __result = this->lexically_relative(__base);
0857 if (__result.native().empty())
0858 return *this;
0859 return __result;
0860 }
0861
0862
0863 class _LIBCPP_EXPORTED_FROM_ABI iterator;
0864 typedef iterator const_iterator;
0865
0866 iterator begin() const;
0867 iterator end() const;
0868
0869 # if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
0870 template <
0871 class _CharT,
0872 class _Traits,
0873 __enable_if_t<is_same<_CharT, value_type>::value && is_same<_Traits, char_traits<value_type> >::value, int> = 0>
0874 _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>&
0875 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
0876 __os << std::__quoted(__p.native());
0877 return __os;
0878 }
0879
0880 template <
0881 class _CharT,
0882 class _Traits,
0883 __enable_if_t<!is_same<_CharT, value_type>::value || !is_same<_Traits, char_traits<value_type> >::value, int> = 0>
0884 _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>&
0885 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
0886 __os << std::__quoted(__p.string<_CharT, _Traits>());
0887 return __os;
0888 }
0889
0890 template <class _CharT, class _Traits>
0891 _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>&
0892 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
0893 basic_string<_CharT, _Traits> __tmp;
0894 __is >> std::__quoted(__tmp);
0895 __p = __tmp;
0896 return __is;
0897 }
0898 # endif
0899
0900 private:
0901 inline _LIBCPP_HIDE_FROM_ABI path& __assign_view(__string_view const& __s) {
0902 __pn_ = string_type(__s);
0903 return *this;
0904 }
0905 string_type __pn_;
0906 };
0907
0908 inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
0909
0910 _LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept;
0911
0912 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
0913
0914 _LIBCPP_END_NAMESPACE_FILESYSTEM
0915
0916 _LIBCPP_BEGIN_NAMESPACE_STD
0917
0918 template <>
0919 struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash<filesystem::path> : __unary_function<filesystem::path, size_t> {
0920 _LIBCPP_HIDE_FROM_ABI size_t operator()(filesystem::path const& __p) const noexcept {
0921 return filesystem::hash_value(__p);
0922 }
0923 };
0924
0925 _LIBCPP_END_NAMESPACE_STD
0926
0927 #endif
0928
0929 _LIBCPP_POP_MACROS
0930
0931 #endif