10eae32dcSDimitry Andric // -*- C++ -*- 20eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 30eae32dcSDimitry Andric // 40eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 60eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70eae32dcSDimitry Andric // 80eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 90eae32dcSDimitry Andric 100eae32dcSDimitry Andric #ifndef _LIBCPP___FILESYSTEM_PATH_H 110eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_PATH_H 120eae32dcSDimitry Andric 1381ad6265SDimitry Andric #include <__algorithm/replace.h> 1481ad6265SDimitry Andric #include <__algorithm/replace_copy.h> 150eae32dcSDimitry Andric #include <__availability> 160eae32dcSDimitry Andric #include <__config> 170eae32dcSDimitry Andric #include <__iterator/back_insert_iterator.h> 180eae32dcSDimitry Andric #include <__iterator/iterator_traits.h> 190eae32dcSDimitry Andric #include <cstddef> 2004eeddc0SDimitry Andric #include <string> 210eae32dcSDimitry Andric #include <string_view> 2204eeddc0SDimitry Andric #include <type_traits> 230eae32dcSDimitry Andric 240eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 250eae32dcSDimitry Andric # include <iomanip> // for quoted 2604eeddc0SDimitry Andric # include <locale> 270eae32dcSDimitry Andric #endif 280eae32dcSDimitry Andric 2981ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 3081ad6265SDimitry Andric # pragma GCC system_header 3181ad6265SDimitry Andric #endif 3281ad6265SDimitry Andric 330eae32dcSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 340eae32dcSDimitry Andric 350eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM 360eae32dcSDimitry Andric 370eae32dcSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 380eae32dcSDimitry Andric 390eae32dcSDimitry Andric template <class _Tp> 400eae32dcSDimitry Andric struct __can_convert_char { 410eae32dcSDimitry Andric static const bool value = false; 420eae32dcSDimitry Andric }; 430eae32dcSDimitry Andric template <class _Tp> 440eae32dcSDimitry Andric struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {}; 450eae32dcSDimitry Andric template <> 460eae32dcSDimitry Andric struct __can_convert_char<char> { 470eae32dcSDimitry Andric static const bool value = true; 480eae32dcSDimitry Andric using __char_type = char; 490eae32dcSDimitry Andric }; 500eae32dcSDimitry Andric template <> 510eae32dcSDimitry Andric struct __can_convert_char<wchar_t> { 520eae32dcSDimitry Andric static const bool value = true; 530eae32dcSDimitry Andric using __char_type = wchar_t; 540eae32dcSDimitry Andric }; 550eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 560eae32dcSDimitry Andric template <> 570eae32dcSDimitry Andric struct __can_convert_char<char8_t> { 580eae32dcSDimitry Andric static const bool value = true; 590eae32dcSDimitry Andric using __char_type = char8_t; 600eae32dcSDimitry Andric }; 610eae32dcSDimitry Andric #endif 620eae32dcSDimitry Andric template <> 630eae32dcSDimitry Andric struct __can_convert_char<char16_t> { 640eae32dcSDimitry Andric static const bool value = true; 650eae32dcSDimitry Andric using __char_type = char16_t; 660eae32dcSDimitry Andric }; 670eae32dcSDimitry Andric template <> 680eae32dcSDimitry Andric struct __can_convert_char<char32_t> { 690eae32dcSDimitry Andric static const bool value = true; 700eae32dcSDimitry Andric using __char_type = char32_t; 710eae32dcSDimitry Andric }; 720eae32dcSDimitry Andric 730eae32dcSDimitry Andric template <class _ECharT> 7481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 750eae32dcSDimitry Andric typename enable_if<__can_convert_char<_ECharT>::value, bool>::type 760eae32dcSDimitry Andric __is_separator(_ECharT __e) { 770eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 780eae32dcSDimitry Andric return __e == _ECharT('/') || __e == _ECharT('\\'); 790eae32dcSDimitry Andric #else 800eae32dcSDimitry Andric return __e == _ECharT('/'); 810eae32dcSDimitry Andric #endif 820eae32dcSDimitry Andric } 830eae32dcSDimitry Andric 840eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 850eae32dcSDimitry Andric typedef u8string __u8_string; 860eae32dcSDimitry Andric #else 870eae32dcSDimitry Andric typedef string __u8_string; 880eae32dcSDimitry Andric #endif 890eae32dcSDimitry Andric 900eae32dcSDimitry Andric struct _NullSentinel {}; 910eae32dcSDimitry Andric 920eae32dcSDimitry Andric template <class _Tp> 930eae32dcSDimitry Andric using _Void = void; 940eae32dcSDimitry Andric 950eae32dcSDimitry Andric template <class _Tp, class = void> 960eae32dcSDimitry Andric struct __is_pathable_string : public false_type {}; 970eae32dcSDimitry Andric 980eae32dcSDimitry Andric template <class _ECharT, class _Traits, class _Alloc> 990eae32dcSDimitry Andric struct __is_pathable_string< 1000eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Alloc>, 1010eae32dcSDimitry Andric _Void<typename __can_convert_char<_ECharT>::__char_type> > 1020eae32dcSDimitry Andric : public __can_convert_char<_ECharT> { 1030eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Alloc>; 1040eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 10581ad6265SDimitry Andric 10681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1070eae32dcSDimitry Andric static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 10881ad6265SDimitry Andric 10981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1100eae32dcSDimitry Andric static _ECharT const* __range_end(_Str const& __s) { 1110eae32dcSDimitry Andric return __s.data() + __s.length(); 1120eae32dcSDimitry Andric } 11381ad6265SDimitry Andric 11481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1150eae32dcSDimitry Andric static _ECharT __first_or_null(_Str const& __s) { 1160eae32dcSDimitry Andric return __s.empty() ? _ECharT{} : __s[0]; 1170eae32dcSDimitry Andric } 1180eae32dcSDimitry Andric }; 1190eae32dcSDimitry Andric 1200eae32dcSDimitry Andric template <class _ECharT, class _Traits> 1210eae32dcSDimitry Andric struct __is_pathable_string< 1220eae32dcSDimitry Andric basic_string_view<_ECharT, _Traits>, 1230eae32dcSDimitry Andric _Void<typename __can_convert_char<_ECharT>::__char_type> > 1240eae32dcSDimitry Andric : public __can_convert_char<_ECharT> { 1250eae32dcSDimitry Andric using _Str = basic_string_view<_ECharT, _Traits>; 1260eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 12781ad6265SDimitry Andric 12881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1290eae32dcSDimitry Andric static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 13081ad6265SDimitry Andric 13181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1320eae32dcSDimitry Andric static _ECharT const* __range_end(_Str const& __s) { 1330eae32dcSDimitry Andric return __s.data() + __s.length(); 1340eae32dcSDimitry Andric } 13581ad6265SDimitry Andric 13681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1370eae32dcSDimitry Andric static _ECharT __first_or_null(_Str const& __s) { 1380eae32dcSDimitry Andric return __s.empty() ? _ECharT{} : __s[0]; 1390eae32dcSDimitry Andric } 1400eae32dcSDimitry Andric }; 1410eae32dcSDimitry Andric 1420eae32dcSDimitry Andric template <class _Source, class _DS = typename decay<_Source>::type, 1430eae32dcSDimitry Andric class _UnqualPtrType = 144*bdd1243dSDimitry Andric __remove_const_t<__remove_pointer_t<_DS> >, 1450eae32dcSDimitry Andric bool _IsCharPtr = is_pointer<_DS>::value&& 1460eae32dcSDimitry Andric __can_convert_char<_UnqualPtrType>::value> 1470eae32dcSDimitry Andric struct __is_pathable_char_array : false_type {}; 1480eae32dcSDimitry Andric 1490eae32dcSDimitry Andric template <class _Source, class _ECharT, class _UPtr> 1500eae32dcSDimitry Andric struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> 151*bdd1243dSDimitry Andric : __can_convert_char<__remove_const_t<_ECharT> > { 152*bdd1243dSDimitry Andric using _Base = __can_convert_char<__remove_const_t<_ECharT> >; 1530eae32dcSDimitry Andric 15481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1550eae32dcSDimitry Andric static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } 15681ad6265SDimitry Andric 15781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1580eae32dcSDimitry Andric static _ECharT const* __range_end(const _ECharT* __b) { 1590eae32dcSDimitry Andric using _Iter = const _ECharT*; 1600eae32dcSDimitry Andric const _ECharT __sentinel = _ECharT{}; 1610eae32dcSDimitry Andric _Iter __e = __b; 1620eae32dcSDimitry Andric for (; *__e != __sentinel; ++__e) 1630eae32dcSDimitry Andric ; 1640eae32dcSDimitry Andric return __e; 1650eae32dcSDimitry Andric } 1660eae32dcSDimitry Andric 16781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1680eae32dcSDimitry Andric static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } 1690eae32dcSDimitry Andric }; 1700eae32dcSDimitry Andric 1710eae32dcSDimitry Andric template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value, 1720eae32dcSDimitry Andric class = void> 1730eae32dcSDimitry Andric struct __is_pathable_iter : false_type {}; 1740eae32dcSDimitry Andric 1750eae32dcSDimitry Andric template <class _Iter> 1760eae32dcSDimitry Andric struct __is_pathable_iter< 1770eae32dcSDimitry Andric _Iter, true, 1780eae32dcSDimitry Andric _Void<typename __can_convert_char< 1790eae32dcSDimitry Andric typename iterator_traits<_Iter>::value_type>::__char_type> > 1800eae32dcSDimitry Andric : __can_convert_char<typename iterator_traits<_Iter>::value_type> { 1810eae32dcSDimitry Andric using _ECharT = typename iterator_traits<_Iter>::value_type; 1820eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 1830eae32dcSDimitry Andric 18481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1850eae32dcSDimitry Andric static _Iter __range_begin(_Iter __b) { return __b; } 18681ad6265SDimitry Andric 18781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1880eae32dcSDimitry Andric static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } 1890eae32dcSDimitry Andric 19081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1910eae32dcSDimitry Andric static _ECharT __first_or_null(_Iter __b) { return *__b; } 1920eae32dcSDimitry Andric }; 1930eae32dcSDimitry Andric 1940eae32dcSDimitry Andric template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, 1950eae32dcSDimitry Andric bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, 1960eae32dcSDimitry Andric bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> 1970eae32dcSDimitry Andric struct __is_pathable : false_type { 1980eae32dcSDimitry Andric static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); 1990eae32dcSDimitry Andric }; 2000eae32dcSDimitry Andric 2010eae32dcSDimitry Andric template <class _Tp> 2020eae32dcSDimitry Andric struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; 2030eae32dcSDimitry Andric 2040eae32dcSDimitry Andric template <class _Tp> 2050eae32dcSDimitry Andric struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { 2060eae32dcSDimitry Andric }; 2070eae32dcSDimitry Andric 2080eae32dcSDimitry Andric template <class _Tp> 2090eae32dcSDimitry Andric struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; 2100eae32dcSDimitry Andric 2110eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2120eae32dcSDimitry Andric typedef wstring __path_string; 2130eae32dcSDimitry Andric typedef wchar_t __path_value; 2140eae32dcSDimitry Andric #else 2150eae32dcSDimitry Andric typedef string __path_string; 2160eae32dcSDimitry Andric typedef char __path_value; 2170eae32dcSDimitry Andric #endif 2180eae32dcSDimitry Andric 2190eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2200eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 2210eae32dcSDimitry Andric size_t __wide_to_char(const wstring&, char*, size_t); 2220eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 2230eae32dcSDimitry Andric size_t __char_to_wide(const string&, wchar_t*, size_t); 2240eae32dcSDimitry Andric #endif 2250eae32dcSDimitry Andric 2260eae32dcSDimitry Andric template <class _ECharT> 2270eae32dcSDimitry Andric struct _PathCVT; 2280eae32dcSDimitry Andric 2290eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 2300eae32dcSDimitry Andric template <class _ECharT> 2310eae32dcSDimitry Andric struct _PathCVT { 2320eae32dcSDimitry Andric static_assert(__can_convert_char<_ECharT>::value, 2330eae32dcSDimitry Andric "Char type not convertible"); 2340eae32dcSDimitry Andric 2350eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower; 2360eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2370eae32dcSDimitry Andric typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener; 2380eae32dcSDimitry Andric #endif 2390eae32dcSDimitry Andric 24081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 2410eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _ECharT const* __b, 2420eae32dcSDimitry Andric _ECharT const* __e) { 2430eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2440eae32dcSDimitry Andric string __utf8; 2450eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __b, __e); 2460eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 2470eae32dcSDimitry Andric #else 2480eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __b, __e); 2490eae32dcSDimitry Andric #endif 2500eae32dcSDimitry Andric } 2510eae32dcSDimitry Andric 2520eae32dcSDimitry Andric template <class _Iter> 25381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 2540eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 2550eae32dcSDimitry Andric static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 2560eae32dcSDimitry Andric if (__b == __e) 2570eae32dcSDimitry Andric return; 2580eae32dcSDimitry Andric basic_string<_ECharT> __tmp(__b, __e); 2590eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2600eae32dcSDimitry Andric string __utf8; 2610eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __tmp.data(), 2620eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 2630eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 2640eae32dcSDimitry Andric #else 2650eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __tmp.data(), 2660eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 2670eae32dcSDimitry Andric #endif 2680eae32dcSDimitry Andric } 2690eae32dcSDimitry Andric 2700eae32dcSDimitry Andric template <class _Iter> 27181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 2720eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 2730eae32dcSDimitry Andric static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 2740eae32dcSDimitry Andric const _ECharT __sentinel = _ECharT{}; 2750eae32dcSDimitry Andric if (*__b == __sentinel) 2760eae32dcSDimitry Andric return; 2770eae32dcSDimitry Andric basic_string<_ECharT> __tmp; 2780eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 2790eae32dcSDimitry Andric __tmp.push_back(*__b); 2800eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 2810eae32dcSDimitry Andric string __utf8; 2820eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __tmp.data(), 2830eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 2840eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 2850eae32dcSDimitry Andric #else 2860eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __tmp.data(), 2870eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 2880eae32dcSDimitry Andric #endif 2890eae32dcSDimitry Andric } 2900eae32dcSDimitry Andric 2910eae32dcSDimitry Andric template <class _Source> 29281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 2930eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 2940eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 2950eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 2960eae32dcSDimitry Andric _Traits::__range_end(__s)); 2970eae32dcSDimitry Andric } 2980eae32dcSDimitry Andric }; 2990eae32dcSDimitry Andric #endif // !_LIBCPP_HAS_NO_LOCALIZATION 3000eae32dcSDimitry Andric 3010eae32dcSDimitry Andric template <> 3020eae32dcSDimitry Andric struct _PathCVT<__path_value> { 3030eae32dcSDimitry Andric 3040eae32dcSDimitry Andric template <class _Iter> 30581ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3060eae32dcSDimitry Andric static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type 3070eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 3080eae32dcSDimitry Andric for (; __b != __e; ++__b) 3090eae32dcSDimitry Andric __dest.push_back(*__b); 3100eae32dcSDimitry Andric } 3110eae32dcSDimitry Andric 3120eae32dcSDimitry Andric template <class _Iter> 31381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3140eae32dcSDimitry Andric static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type 3150eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 3160eae32dcSDimitry Andric __dest.append(__b, __e); 3170eae32dcSDimitry Andric } 3180eae32dcSDimitry Andric 3190eae32dcSDimitry Andric template <class _Iter> 32081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3210eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 3220eae32dcSDimitry Andric const char __sentinel = char{}; 3230eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 3240eae32dcSDimitry Andric __dest.push_back(*__b); 3250eae32dcSDimitry Andric } 3260eae32dcSDimitry Andric 3270eae32dcSDimitry Andric template <class _Source> 32881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3290eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 3300eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 3310eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 3320eae32dcSDimitry Andric _Traits::__range_end(__s)); 3330eae32dcSDimitry Andric } 3340eae32dcSDimitry Andric }; 3350eae32dcSDimitry Andric 3360eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 3370eae32dcSDimitry Andric template <> 3380eae32dcSDimitry Andric struct _PathCVT<char> { 3390eae32dcSDimitry Andric 34081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3410eae32dcSDimitry Andric static void 3420eae32dcSDimitry Andric __append_string(__path_string& __dest, const basic_string<char> &__str) { 3430eae32dcSDimitry Andric size_t __size = __char_to_wide(__str, nullptr, 0); 3440eae32dcSDimitry Andric size_t __pos = __dest.size(); 3450eae32dcSDimitry Andric __dest.resize(__pos + __size); 3460eae32dcSDimitry Andric __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); 3470eae32dcSDimitry Andric } 3480eae32dcSDimitry Andric 3490eae32dcSDimitry Andric template <class _Iter> 35081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3510eae32dcSDimitry Andric static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type 3520eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 3530eae32dcSDimitry Andric basic_string<char> __tmp(__b, __e); 3540eae32dcSDimitry Andric __append_string(__dest, __tmp); 3550eae32dcSDimitry Andric } 3560eae32dcSDimitry Andric 3570eae32dcSDimitry Andric template <class _Iter> 35881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3590eae32dcSDimitry Andric static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type 3600eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 3610eae32dcSDimitry Andric basic_string<char> __tmp(__b, __e); 3620eae32dcSDimitry Andric __append_string(__dest, __tmp); 3630eae32dcSDimitry Andric } 3640eae32dcSDimitry Andric 3650eae32dcSDimitry Andric template <class _Iter> 36681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3670eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 3680eae32dcSDimitry Andric const char __sentinel = char{}; 3690eae32dcSDimitry Andric basic_string<char> __tmp; 3700eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 3710eae32dcSDimitry Andric __tmp.push_back(*__b); 3720eae32dcSDimitry Andric __append_string(__dest, __tmp); 3730eae32dcSDimitry Andric } 3740eae32dcSDimitry Andric 3750eae32dcSDimitry Andric template <class _Source> 37681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3770eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 3780eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 3790eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 3800eae32dcSDimitry Andric _Traits::__range_end(__s)); 3810eae32dcSDimitry Andric } 3820eae32dcSDimitry Andric }; 3830eae32dcSDimitry Andric 3840eae32dcSDimitry Andric template <class _ECharT> 3850eae32dcSDimitry Andric struct _PathExport { 3860eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; 3870eae32dcSDimitry Andric typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener; 3880eae32dcSDimitry Andric 3890eae32dcSDimitry Andric template <class _Str> 39081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 3910eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 3920eae32dcSDimitry Andric string __utf8; 3930eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); 3940eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 3950eae32dcSDimitry Andric } 3960eae32dcSDimitry Andric }; 3970eae32dcSDimitry Andric 3980eae32dcSDimitry Andric template <> 3990eae32dcSDimitry Andric struct _PathExport<char> { 4000eae32dcSDimitry Andric template <class _Str> 40181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4020eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 4030eae32dcSDimitry Andric size_t __size = __wide_to_char(__src, nullptr, 0); 4040eae32dcSDimitry Andric size_t __pos = __dest.size(); 4050eae32dcSDimitry Andric __dest.resize(__size); 4060eae32dcSDimitry Andric __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size); 4070eae32dcSDimitry Andric } 4080eae32dcSDimitry Andric }; 4090eae32dcSDimitry Andric 4100eae32dcSDimitry Andric template <> 4110eae32dcSDimitry Andric struct _PathExport<wchar_t> { 4120eae32dcSDimitry Andric template <class _Str> 41381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4140eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 4150eae32dcSDimitry Andric __dest.append(__src.begin(), __src.end()); 4160eae32dcSDimitry Andric } 4170eae32dcSDimitry Andric }; 4180eae32dcSDimitry Andric 4190eae32dcSDimitry Andric template <> 4200eae32dcSDimitry Andric struct _PathExport<char16_t> { 4210eae32dcSDimitry Andric template <class _Str> 42281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4230eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 4240eae32dcSDimitry Andric __dest.append(__src.begin(), __src.end()); 4250eae32dcSDimitry Andric } 4260eae32dcSDimitry Andric }; 4270eae32dcSDimitry Andric 4280eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 4290eae32dcSDimitry Andric template <> 4300eae32dcSDimitry Andric struct _PathExport<char8_t> { 4310eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; 4320eae32dcSDimitry Andric 4330eae32dcSDimitry Andric template <class _Str> 43481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4350eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 4360eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); 4370eae32dcSDimitry Andric } 4380eae32dcSDimitry Andric }; 4390eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_CHAR8_T */ 4400eae32dcSDimitry Andric #endif /* _LIBCPP_WIN32API */ 4410eae32dcSDimitry Andric 4420eae32dcSDimitry Andric class _LIBCPP_TYPE_VIS path { 4430eae32dcSDimitry Andric template <class _SourceOrIter, class _Tp = path&> 4440eae32dcSDimitry Andric using _EnableIfPathable = 4450eae32dcSDimitry Andric typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; 4460eae32dcSDimitry Andric 4470eae32dcSDimitry Andric template <class _Tp> 4480eae32dcSDimitry Andric using _SourceChar = typename __is_pathable<_Tp>::__char_type; 4490eae32dcSDimitry Andric 4500eae32dcSDimitry Andric template <class _Tp> 4510eae32dcSDimitry Andric using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; 4520eae32dcSDimitry Andric 4530eae32dcSDimitry Andric public: 4540eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 4550eae32dcSDimitry Andric typedef wchar_t value_type; 4560eae32dcSDimitry Andric static constexpr value_type preferred_separator = L'\\'; 4570eae32dcSDimitry Andric #else 4580eae32dcSDimitry Andric typedef char value_type; 4590eae32dcSDimitry Andric static constexpr value_type preferred_separator = '/'; 4600eae32dcSDimitry Andric #endif 4610eae32dcSDimitry Andric typedef basic_string<value_type> string_type; 4620eae32dcSDimitry Andric typedef basic_string_view<value_type> __string_view; 4630eae32dcSDimitry Andric 4640eae32dcSDimitry Andric enum _LIBCPP_ENUM_VIS format : unsigned char { 4650eae32dcSDimitry Andric auto_format, 4660eae32dcSDimitry Andric native_format, 4670eae32dcSDimitry Andric generic_format 4680eae32dcSDimitry Andric }; 4690eae32dcSDimitry Andric 4700eae32dcSDimitry Andric // constructors and destructor 47181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path() noexcept {} 47281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {} 47381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept 4740eae32dcSDimitry Andric : __pn_(_VSTD::move(__p.__pn_)) {} 4750eae32dcSDimitry Andric 47681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4770eae32dcSDimitry Andric path(string_type&& __s, format = format::auto_format) noexcept 4780eae32dcSDimitry Andric : __pn_(_VSTD::move(__s)) {} 4790eae32dcSDimitry Andric 4800eae32dcSDimitry Andric template <class _Source, class = _EnableIfPathable<_Source, void> > 48181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4820eae32dcSDimitry Andric path(const _Source& __src, format = format::auto_format) { 4830eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __src); 4840eae32dcSDimitry Andric } 4850eae32dcSDimitry Andric 4860eae32dcSDimitry Andric template <class _InputIt> 48781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 4880eae32dcSDimitry Andric path(_InputIt __first, _InputIt __last, format = format::auto_format) { 4890eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 4900eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 4910eae32dcSDimitry Andric } 4920eae32dcSDimitry Andric 4930eae32dcSDimitry Andric /* 4940eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 4950eae32dcSDimitry Andric // TODO Implement locale conversions. 4960eae32dcSDimitry Andric template <class _Source, class = _EnableIfPathable<_Source, void> > 4970eae32dcSDimitry Andric path(const _Source& __src, const locale& __loc, format = format::auto_format); 4980eae32dcSDimitry Andric template <class _InputIt> 4990eae32dcSDimitry Andric path(_InputIt __first, _InputIt _last, const locale& __loc, 5000eae32dcSDimitry Andric format = format::auto_format); 5010eae32dcSDimitry Andric #endif 5020eae32dcSDimitry Andric */ 5030eae32dcSDimitry Andric 50481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5050eae32dcSDimitry Andric ~path() = default; 5060eae32dcSDimitry Andric 5070eae32dcSDimitry Andric // assignments 50881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5090eae32dcSDimitry Andric path& operator=(const path& __p) { 5100eae32dcSDimitry Andric __pn_ = __p.__pn_; 5110eae32dcSDimitry Andric return *this; 5120eae32dcSDimitry Andric } 5130eae32dcSDimitry Andric 51481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5150eae32dcSDimitry Andric path& operator=(path&& __p) noexcept { 5160eae32dcSDimitry Andric __pn_ = _VSTD::move(__p.__pn_); 5170eae32dcSDimitry Andric return *this; 5180eae32dcSDimitry Andric } 5190eae32dcSDimitry Andric 52081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5210eae32dcSDimitry Andric path& operator=(string_type&& __s) noexcept { 5220eae32dcSDimitry Andric __pn_ = _VSTD::move(__s); 5230eae32dcSDimitry Andric return *this; 5240eae32dcSDimitry Andric } 5250eae32dcSDimitry Andric 52681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5270eae32dcSDimitry Andric path& assign(string_type&& __s) noexcept { 5280eae32dcSDimitry Andric __pn_ = _VSTD::move(__s); 5290eae32dcSDimitry Andric return *this; 5300eae32dcSDimitry Andric } 5310eae32dcSDimitry Andric 5320eae32dcSDimitry Andric template <class _Source> 53381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> 5340eae32dcSDimitry Andric operator=(const _Source& __src) { 5350eae32dcSDimitry Andric return this->assign(__src); 5360eae32dcSDimitry Andric } 5370eae32dcSDimitry Andric 5380eae32dcSDimitry Andric template <class _Source> 53981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5400eae32dcSDimitry Andric _EnableIfPathable<_Source> assign(const _Source& __src) { 5410eae32dcSDimitry Andric __pn_.clear(); 5420eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __src); 5430eae32dcSDimitry Andric return *this; 5440eae32dcSDimitry Andric } 5450eae32dcSDimitry Andric 5460eae32dcSDimitry Andric template <class _InputIt> 54781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5480eae32dcSDimitry Andric path& assign(_InputIt __first, _InputIt __last) { 5490eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 5500eae32dcSDimitry Andric __pn_.clear(); 5510eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 5520eae32dcSDimitry Andric return *this; 5530eae32dcSDimitry Andric } 5540eae32dcSDimitry Andric 5550eae32dcSDimitry Andric public: 5560eae32dcSDimitry Andric // appends 5570eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 55881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5590eae32dcSDimitry Andric path& operator/=(const path& __p) { 5600eae32dcSDimitry Andric auto __p_root_name = __p.__root_name(); 5610eae32dcSDimitry Andric auto __p_root_name_size = __p_root_name.size(); 5620eae32dcSDimitry Andric if (__p.is_absolute() || 5630eae32dcSDimitry Andric (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { 5640eae32dcSDimitry Andric __pn_ = __p.__pn_; 5650eae32dcSDimitry Andric return *this; 5660eae32dcSDimitry Andric } 5670eae32dcSDimitry Andric if (__p.has_root_directory()) { 5680eae32dcSDimitry Andric path __root_name_str = root_name(); 5690eae32dcSDimitry Andric __pn_ = __root_name_str.native(); 5700eae32dcSDimitry Andric __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 5710eae32dcSDimitry Andric return *this; 5720eae32dcSDimitry Andric } 5730eae32dcSDimitry Andric if (has_filename() || (!has_root_directory() && is_absolute())) 5740eae32dcSDimitry Andric __pn_ += preferred_separator; 5750eae32dcSDimitry Andric __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 5760eae32dcSDimitry Andric return *this; 5770eae32dcSDimitry Andric } 5780eae32dcSDimitry Andric template <class _Source> 5790eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 5800eae32dcSDimitry Andric operator/=(const _Source& __src) { 5810eae32dcSDimitry Andric return operator/=(path(__src)); 5820eae32dcSDimitry Andric } 5830eae32dcSDimitry Andric 5840eae32dcSDimitry Andric template <class _Source> 58581ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5860eae32dcSDimitry Andric _EnableIfPathable<_Source> append(const _Source& __src) { 5870eae32dcSDimitry Andric return operator/=(path(__src)); 5880eae32dcSDimitry Andric } 5890eae32dcSDimitry Andric 5900eae32dcSDimitry Andric template <class _InputIt> 59181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5920eae32dcSDimitry Andric path& append(_InputIt __first, _InputIt __last) { 5930eae32dcSDimitry Andric return operator/=(path(__first, __last)); 5940eae32dcSDimitry Andric } 5950eae32dcSDimitry Andric #else 59681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 5970eae32dcSDimitry Andric path& operator/=(const path& __p) { 5980eae32dcSDimitry Andric if (__p.is_absolute()) { 5990eae32dcSDimitry Andric __pn_ = __p.__pn_; 6000eae32dcSDimitry Andric return *this; 6010eae32dcSDimitry Andric } 6020eae32dcSDimitry Andric if (has_filename()) 6030eae32dcSDimitry Andric __pn_ += preferred_separator; 6040eae32dcSDimitry Andric __pn_ += __p.native(); 6050eae32dcSDimitry Andric return *this; 6060eae32dcSDimitry Andric } 6070eae32dcSDimitry Andric 6080eae32dcSDimitry Andric // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src 6090eae32dcSDimitry Andric // is known at compile time to be "/' since the user almost certainly intended 6100eae32dcSDimitry Andric // to append a separator instead of overwriting the path with "/" 6110eae32dcSDimitry Andric template <class _Source> 61281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> 6130eae32dcSDimitry Andric operator/=(const _Source& __src) { 6140eae32dcSDimitry Andric return this->append(__src); 6150eae32dcSDimitry Andric } 6160eae32dcSDimitry Andric 6170eae32dcSDimitry Andric template <class _Source> 61881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6190eae32dcSDimitry Andric _EnableIfPathable<_Source> append(const _Source& __src) { 6200eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 6210eae32dcSDimitry Andric using _CVT = _PathCVT<_SourceChar<_Source> >; 622*bdd1243dSDimitry Andric bool __source_is_absolute = _VSTD_FS::__is_separator(_Traits::__first_or_null(__src)); 6230eae32dcSDimitry Andric if (__source_is_absolute) 6240eae32dcSDimitry Andric __pn_.clear(); 6250eae32dcSDimitry Andric else if (has_filename()) 6260eae32dcSDimitry Andric __pn_ += preferred_separator; 6270eae32dcSDimitry Andric _CVT::__append_source(__pn_, __src); 6280eae32dcSDimitry Andric return *this; 6290eae32dcSDimitry Andric } 6300eae32dcSDimitry Andric 6310eae32dcSDimitry Andric template <class _InputIt> 63281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6330eae32dcSDimitry Andric path& append(_InputIt __first, _InputIt __last) { 6340eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 6350eae32dcSDimitry Andric static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); 6360eae32dcSDimitry Andric using _CVT = _PathCVT<_ItVal>; 637*bdd1243dSDimitry Andric if (__first != __last && _VSTD_FS::__is_separator(*__first)) 6380eae32dcSDimitry Andric __pn_.clear(); 6390eae32dcSDimitry Andric else if (has_filename()) 6400eae32dcSDimitry Andric __pn_ += preferred_separator; 6410eae32dcSDimitry Andric _CVT::__append_range(__pn_, __first, __last); 6420eae32dcSDimitry Andric return *this; 6430eae32dcSDimitry Andric } 6440eae32dcSDimitry Andric #endif 6450eae32dcSDimitry Andric 6460eae32dcSDimitry Andric // concatenation 64781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6480eae32dcSDimitry Andric path& operator+=(const path& __x) { 6490eae32dcSDimitry Andric __pn_ += __x.__pn_; 6500eae32dcSDimitry Andric return *this; 6510eae32dcSDimitry Andric } 6520eae32dcSDimitry Andric 65381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6540eae32dcSDimitry Andric path& operator+=(const string_type& __x) { 6550eae32dcSDimitry Andric __pn_ += __x; 6560eae32dcSDimitry Andric return *this; 6570eae32dcSDimitry Andric } 6580eae32dcSDimitry Andric 65981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6600eae32dcSDimitry Andric path& operator+=(__string_view __x) { 6610eae32dcSDimitry Andric __pn_ += __x; 6620eae32dcSDimitry Andric return *this; 6630eae32dcSDimitry Andric } 6640eae32dcSDimitry Andric 66581ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6660eae32dcSDimitry Andric path& operator+=(const value_type* __x) { 6670eae32dcSDimitry Andric __pn_ += __x; 6680eae32dcSDimitry Andric return *this; 6690eae32dcSDimitry Andric } 6700eae32dcSDimitry Andric 67181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6720eae32dcSDimitry Andric path& operator+=(value_type __x) { 6730eae32dcSDimitry Andric __pn_ += __x; 6740eae32dcSDimitry Andric return *this; 6750eae32dcSDimitry Andric } 6760eae32dcSDimitry Andric 6770eae32dcSDimitry Andric template <class _ECharT> 67881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6790eae32dcSDimitry Andric typename enable_if<__can_convert_char<_ECharT>::value, path&>::type 6800eae32dcSDimitry Andric operator+=(_ECharT __x) { 6810eae32dcSDimitry Andric _PathCVT<_ECharT>::__append_source(__pn_, 6820eae32dcSDimitry Andric basic_string_view<_ECharT>(&__x, 1)); 6830eae32dcSDimitry Andric return *this; 6840eae32dcSDimitry Andric } 6850eae32dcSDimitry Andric 6860eae32dcSDimitry Andric template <class _Source> 68781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6880eae32dcSDimitry Andric _EnableIfPathable<_Source> operator+=(const _Source& __x) { 6890eae32dcSDimitry Andric return this->concat(__x); 6900eae32dcSDimitry Andric } 6910eae32dcSDimitry Andric 6920eae32dcSDimitry Andric template <class _Source> 69381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 6940eae32dcSDimitry Andric _EnableIfPathable<_Source> concat(const _Source& __x) { 6950eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __x); 6960eae32dcSDimitry Andric return *this; 6970eae32dcSDimitry Andric } 6980eae32dcSDimitry Andric 6990eae32dcSDimitry Andric template <class _InputIt> 70081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7010eae32dcSDimitry Andric path& concat(_InputIt __first, _InputIt __last) { 7020eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 7030eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 7040eae32dcSDimitry Andric return *this; 7050eae32dcSDimitry Andric } 7060eae32dcSDimitry Andric 7070eae32dcSDimitry Andric // modifiers 70881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7090eae32dcSDimitry Andric void clear() noexcept { __pn_.clear(); } 7100eae32dcSDimitry Andric 71181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7120eae32dcSDimitry Andric path& make_preferred() { 7130eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 7140eae32dcSDimitry Andric _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); 7150eae32dcSDimitry Andric #endif 7160eae32dcSDimitry Andric return *this; 7170eae32dcSDimitry Andric } 7180eae32dcSDimitry Andric 71981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7200eae32dcSDimitry Andric path& remove_filename() { 7210eae32dcSDimitry Andric auto __fname = __filename(); 7220eae32dcSDimitry Andric if (!__fname.empty()) 7230eae32dcSDimitry Andric __pn_.erase(__fname.data() - __pn_.data()); 7240eae32dcSDimitry Andric return *this; 7250eae32dcSDimitry Andric } 7260eae32dcSDimitry Andric 72781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7280eae32dcSDimitry Andric path& replace_filename(const path& __replacement) { 7290eae32dcSDimitry Andric remove_filename(); 7300eae32dcSDimitry Andric return (*this /= __replacement); 7310eae32dcSDimitry Andric } 7320eae32dcSDimitry Andric 7330eae32dcSDimitry Andric path& replace_extension(const path& __replacement = path()); 7340eae32dcSDimitry Andric 735*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& __rhs) noexcept { 736*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) == 0; 737*bdd1243dSDimitry Andric } 738*bdd1243dSDimitry Andric # if _LIBCPP_STD_VER <= 17 739*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const path& __lhs, const path& __rhs) noexcept { 740*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) != 0; 741*bdd1243dSDimitry Andric } 742*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator<(const path& __lhs, const path& __rhs) noexcept { 743*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) < 0; 744*bdd1243dSDimitry Andric } 745*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator<=(const path& __lhs, const path& __rhs) noexcept { 746*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) <= 0; 747*bdd1243dSDimitry Andric } 748*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator>(const path& __lhs, const path& __rhs) noexcept { 749*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) > 0; 750*bdd1243dSDimitry Andric } 751*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept { 752*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) >= 0; 753*bdd1243dSDimitry Andric } 754*bdd1243dSDimitry Andric # else // _LIBCPP_STD_VER <= 17 755*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept { 756*bdd1243dSDimitry Andric return __lhs.__compare(__rhs.__pn_) <=> 0; 757*bdd1243dSDimitry Andric } 758*bdd1243dSDimitry Andric # endif // _LIBCPP_STD_VER <= 17 759*bdd1243dSDimitry Andric 760*bdd1243dSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI path operator/(const path& __lhs, const path& __rhs) { 761*bdd1243dSDimitry Andric path __result(__lhs); 762*bdd1243dSDimitry Andric __result /= __rhs; 763*bdd1243dSDimitry Andric return __result; 764*bdd1243dSDimitry Andric } 765*bdd1243dSDimitry Andric 76681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7670eae32dcSDimitry Andric void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } 7680eae32dcSDimitry Andric 7690eae32dcSDimitry Andric // private helper to allow reserving memory in the path 77081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7710eae32dcSDimitry Andric void __reserve(size_t __s) { __pn_.reserve(__s); } 7720eae32dcSDimitry Andric 7730eae32dcSDimitry Andric // native format observers 77481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7750eae32dcSDimitry Andric const string_type& native() const noexcept { return __pn_; } 7760eae32dcSDimitry Andric 77781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7780eae32dcSDimitry Andric const value_type* c_str() const noexcept { return __pn_.c_str(); } 7790eae32dcSDimitry Andric 78081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; } 7810eae32dcSDimitry Andric 7820eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 78381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { return __pn_; } 7840eae32dcSDimitry Andric 78581ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7860eae32dcSDimitry Andric _VSTD::wstring generic_wstring() const { 7870eae32dcSDimitry Andric _VSTD::wstring __s; 7880eae32dcSDimitry Andric __s.resize(__pn_.size()); 7890eae32dcSDimitry Andric _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); 7900eae32dcSDimitry Andric return __s; 7910eae32dcSDimitry Andric } 7920eae32dcSDimitry Andric 7930eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 7940eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 7950eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 79681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 7970eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 7980eae32dcSDimitry Andric string(const _Allocator& __a = _Allocator()) const { 7990eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 8000eae32dcSDimitry Andric _Str __s(__a); 8010eae32dcSDimitry Andric __s.reserve(__pn_.size()); 8020eae32dcSDimitry Andric _PathExport<_ECharT>::__append(__s, __pn_); 8030eae32dcSDimitry Andric return __s; 8040eae32dcSDimitry Andric } 8050eae32dcSDimitry Andric 80681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { 8070eae32dcSDimitry Andric return string<char>(); 8080eae32dcSDimitry Andric } 80981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const { 8100eae32dcSDimitry Andric using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 8110eae32dcSDimitry Andric __u8_string __s; 8120eae32dcSDimitry Andric __s.reserve(__pn_.size()); 8130eae32dcSDimitry Andric _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 8140eae32dcSDimitry Andric return __s; 8150eae32dcSDimitry Andric } 8160eae32dcSDimitry Andric 81781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { 8180eae32dcSDimitry Andric return string<char16_t>(); 8190eae32dcSDimitry Andric } 82081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { 8210eae32dcSDimitry Andric return string<char32_t>(); 8220eae32dcSDimitry Andric } 8230eae32dcSDimitry Andric 8240eae32dcSDimitry Andric // generic format observers 8250eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 8260eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 82781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 8280eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 8290eae32dcSDimitry Andric generic_string(const _Allocator& __a = _Allocator()) const { 8300eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 8310eae32dcSDimitry Andric _Str __s = string<_ECharT, _Traits, _Allocator>(__a); 8320eae32dcSDimitry Andric // Note: This (and generic_u8string below) is slightly suboptimal as 8330eae32dcSDimitry Andric // it iterates twice over the string; once to convert it to the right 8340eae32dcSDimitry Andric // character type, and once to replace path delimiters. 8350eae32dcSDimitry Andric _VSTD::replace(__s.begin(), __s.end(), 8360eae32dcSDimitry Andric static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); 8370eae32dcSDimitry Andric return __s; 8380eae32dcSDimitry Andric } 8390eae32dcSDimitry Andric 84081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return generic_string<char>(); } 84181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); } 84281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); } 84381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 8440eae32dcSDimitry Andric __u8_string generic_u8string() const { 8450eae32dcSDimitry Andric __u8_string __s = u8string(); 8460eae32dcSDimitry Andric _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); 8470eae32dcSDimitry Andric return __s; 8480eae32dcSDimitry Andric } 8490eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 8500eae32dcSDimitry Andric #else /* _LIBCPP_WIN32API */ 8510eae32dcSDimitry Andric 85281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { return __pn_; } 8530eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 85481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 8550eae32dcSDimitry Andric #else 85681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string u8string() const { return __pn_; } 8570eae32dcSDimitry Andric #endif 8580eae32dcSDimitry Andric 8590eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 8600eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 8610eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 86281ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 8630eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 8640eae32dcSDimitry Andric string(const _Allocator& __a = _Allocator()) const { 8650eae32dcSDimitry Andric using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>; 8660eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 8670eae32dcSDimitry Andric _Str __s(__a); 8680eae32dcSDimitry Andric __s.reserve(__pn_.size()); 869*bdd1243dSDimitry Andric _CVT()(std::back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 8700eae32dcSDimitry Andric return __s; 8710eae32dcSDimitry Andric } 8720eae32dcSDimitry Andric 8730eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 87481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { 8750eae32dcSDimitry Andric return string<wchar_t>(); 8760eae32dcSDimitry Andric } 8770eae32dcSDimitry Andric #endif 87881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { 8790eae32dcSDimitry Andric return string<char16_t>(); 8800eae32dcSDimitry Andric } 88181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { 8820eae32dcSDimitry Andric return string<char32_t>(); 8830eae32dcSDimitry Andric } 8840eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 8850eae32dcSDimitry Andric 8860eae32dcSDimitry Andric // generic format observers 88781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return __pn_; } 8880eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 88981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 8900eae32dcSDimitry Andric #else 89181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_u8string() const { return __pn_; } 8920eae32dcSDimitry Andric #endif 8930eae32dcSDimitry Andric 8940eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 8950eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 8960eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 89781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI 8980eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 8990eae32dcSDimitry Andric generic_string(const _Allocator& __a = _Allocator()) const { 9000eae32dcSDimitry Andric return string<_ECharT, _Traits, _Allocator>(__a); 9010eae32dcSDimitry Andric } 9020eae32dcSDimitry Andric 9030eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 90481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::wstring generic_wstring() const { return string<wchar_t>(); } 9050eae32dcSDimitry Andric #endif 90681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return string<char16_t>(); } 90781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return string<char32_t>(); } 9080eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 9090eae32dcSDimitry Andric #endif /* !_LIBCPP_WIN32API */ 9100eae32dcSDimitry Andric 9110eae32dcSDimitry Andric private: 9120eae32dcSDimitry Andric int __compare(__string_view) const; 9130eae32dcSDimitry Andric __string_view __root_name() const; 9140eae32dcSDimitry Andric __string_view __root_directory() const; 9150eae32dcSDimitry Andric __string_view __root_path_raw() const; 9160eae32dcSDimitry Andric __string_view __relative_path() const; 9170eae32dcSDimitry Andric __string_view __parent_path() const; 9180eae32dcSDimitry Andric __string_view __filename() const; 9190eae32dcSDimitry Andric __string_view __stem() const; 9200eae32dcSDimitry Andric __string_view __extension() const; 9210eae32dcSDimitry Andric 9220eae32dcSDimitry Andric public: 9230eae32dcSDimitry Andric // compare 92481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { 9250eae32dcSDimitry Andric return __compare(__p.__pn_); 9260eae32dcSDimitry Andric } 92781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { 9280eae32dcSDimitry Andric return __compare(__s); 9290eae32dcSDimitry Andric } 93081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { 9310eae32dcSDimitry Andric return __compare(__s); 9320eae32dcSDimitry Andric } 93381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { 9340eae32dcSDimitry Andric return __compare(__s); 9350eae32dcSDimitry Andric } 9360eae32dcSDimitry Andric 9370eae32dcSDimitry Andric // decomposition 93881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path root_name() const { 9390eae32dcSDimitry Andric return string_type(__root_name()); 9400eae32dcSDimitry Andric } 94181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path root_directory() const { 9420eae32dcSDimitry Andric return string_type(__root_directory()); 9430eae32dcSDimitry Andric } 94481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path root_path() const { 9450eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 9460eae32dcSDimitry Andric return string_type(__root_path_raw()); 9470eae32dcSDimitry Andric #else 9480eae32dcSDimitry Andric return root_name().append(string_type(__root_directory())); 9490eae32dcSDimitry Andric #endif 9500eae32dcSDimitry Andric } 95181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path relative_path() const { 9520eae32dcSDimitry Andric return string_type(__relative_path()); 9530eae32dcSDimitry Andric } 95481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path parent_path() const { 9550eae32dcSDimitry Andric return string_type(__parent_path()); 9560eae32dcSDimitry Andric } 95781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path filename() const { 9580eae32dcSDimitry Andric return string_type(__filename()); 9590eae32dcSDimitry Andric } 96081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); } 96181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path extension() const { 9620eae32dcSDimitry Andric return string_type(__extension()); 9630eae32dcSDimitry Andric } 9640eae32dcSDimitry Andric 9650eae32dcSDimitry Andric // query 96681ad6265SDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool 9670eae32dcSDimitry Andric empty() const noexcept { 9680eae32dcSDimitry Andric return __pn_.empty(); 9690eae32dcSDimitry Andric } 9700eae32dcSDimitry Andric 97181ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { 9720eae32dcSDimitry Andric return !__root_name().empty(); 9730eae32dcSDimitry Andric } 97481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { 9750eae32dcSDimitry Andric return !__root_directory().empty(); 9760eae32dcSDimitry Andric } 97781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { 9780eae32dcSDimitry Andric return !__root_path_raw().empty(); 9790eae32dcSDimitry Andric } 98081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { 9810eae32dcSDimitry Andric return !__relative_path().empty(); 9820eae32dcSDimitry Andric } 98381ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { 9840eae32dcSDimitry Andric return !__parent_path().empty(); 9850eae32dcSDimitry Andric } 98681ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_filename() const { 9870eae32dcSDimitry Andric return !__filename().empty(); 9880eae32dcSDimitry Andric } 98981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); } 99081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_extension() const { 9910eae32dcSDimitry Andric return !__extension().empty(); 9920eae32dcSDimitry Andric } 9930eae32dcSDimitry Andric 99481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_absolute() const { 9950eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 9960eae32dcSDimitry Andric __string_view __root_name_str = __root_name(); 9970eae32dcSDimitry Andric __string_view __root_dir = __root_directory(); 9980eae32dcSDimitry Andric if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { 9990eae32dcSDimitry Andric // A drive letter with no root directory is relative, e.g. x:example. 10000eae32dcSDimitry Andric return !__root_dir.empty(); 10010eae32dcSDimitry Andric } 10020eae32dcSDimitry Andric // If no root name, it's relative, e.g. \example is relative to the current drive 10030eae32dcSDimitry Andric if (__root_name_str.empty()) 10040eae32dcSDimitry Andric return false; 10050eae32dcSDimitry Andric if (__root_name_str.size() < 3) 10060eae32dcSDimitry Andric return false; 10070eae32dcSDimitry Andric // A server root name, like \\server, is always absolute 10080eae32dcSDimitry Andric if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') 10090eae32dcSDimitry Andric return false; 10100eae32dcSDimitry Andric if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') 10110eae32dcSDimitry Andric return false; 10120eae32dcSDimitry Andric // Seems to be a server root name 10130eae32dcSDimitry Andric return true; 10140eae32dcSDimitry Andric #else 10150eae32dcSDimitry Andric return has_root_directory(); 10160eae32dcSDimitry Andric #endif 10170eae32dcSDimitry Andric } 101881ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); } 10190eae32dcSDimitry Andric 10200eae32dcSDimitry Andric // relative paths 10210eae32dcSDimitry Andric path lexically_normal() const; 10220eae32dcSDimitry Andric path lexically_relative(const path& __base) const; 10230eae32dcSDimitry Andric 102481ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const { 10250eae32dcSDimitry Andric path __result = this->lexically_relative(__base); 10260eae32dcSDimitry Andric if (__result.native().empty()) 10270eae32dcSDimitry Andric return *this; 10280eae32dcSDimitry Andric return __result; 10290eae32dcSDimitry Andric } 10300eae32dcSDimitry Andric 10310eae32dcSDimitry Andric // iterators 10320eae32dcSDimitry Andric class _LIBCPP_TYPE_VIS iterator; 10330eae32dcSDimitry Andric typedef iterator const_iterator; 10340eae32dcSDimitry Andric 10350eae32dcSDimitry Andric iterator begin() const; 10360eae32dcSDimitry Andric iterator end() const; 10370eae32dcSDimitry Andric 10380eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 10390eae32dcSDimitry Andric template <class _CharT, class _Traits> 104081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 10410eae32dcSDimitry Andric typename enable_if<is_same<_CharT, value_type>::value && 10420eae32dcSDimitry Andric is_same<_Traits, char_traits<value_type> >::value, 10430eae32dcSDimitry Andric basic_ostream<_CharT, _Traits>&>::type 10440eae32dcSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 10450eae32dcSDimitry Andric __os << _VSTD::__quoted(__p.native()); 10460eae32dcSDimitry Andric return __os; 10470eae32dcSDimitry Andric } 10480eae32dcSDimitry Andric 10490eae32dcSDimitry Andric template <class _CharT, class _Traits> 105081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI friend 10510eae32dcSDimitry Andric typename enable_if<!is_same<_CharT, value_type>::value || 10520eae32dcSDimitry Andric !is_same<_Traits, char_traits<value_type> >::value, 10530eae32dcSDimitry Andric basic_ostream<_CharT, _Traits>&>::type 10540eae32dcSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 10550eae32dcSDimitry Andric __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); 10560eae32dcSDimitry Andric return __os; 10570eae32dcSDimitry Andric } 10580eae32dcSDimitry Andric 10590eae32dcSDimitry Andric template <class _CharT, class _Traits> 106081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>& 10610eae32dcSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { 10620eae32dcSDimitry Andric basic_string<_CharT, _Traits> __tmp; 106381ad6265SDimitry Andric __is >> _VSTD::__quoted(__tmp); 10640eae32dcSDimitry Andric __p = __tmp; 10650eae32dcSDimitry Andric return __is; 10660eae32dcSDimitry Andric } 10670eae32dcSDimitry Andric #endif // !_LIBCPP_HAS_NO_LOCALIZATION 10680eae32dcSDimitry Andric 10690eae32dcSDimitry Andric private: 107081ad6265SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI path& 10710eae32dcSDimitry Andric __assign_view(__string_view const& __s) noexcept { 10720eae32dcSDimitry Andric __pn_ = string_type(__s); 10730eae32dcSDimitry Andric return *this; 10740eae32dcSDimitry Andric } 10750eae32dcSDimitry Andric string_type __pn_; 10760eae32dcSDimitry Andric }; 10770eae32dcSDimitry Andric 107881ad6265SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { 10790eae32dcSDimitry Andric __lhs.swap(__rhs); 10800eae32dcSDimitry Andric } 10810eae32dcSDimitry Andric 10820eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 10830eae32dcSDimitry Andric size_t hash_value(const path& __p) noexcept; 10840eae32dcSDimitry Andric 10850eae32dcSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_POP 10860eae32dcSDimitry Andric 10870eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM 10880eae32dcSDimitry Andric 10890eae32dcSDimitry Andric #endif // _LIBCPP_CXX03_LANG 10900eae32dcSDimitry Andric 10910eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_PATH_H 1092