1*0eae32dcSDimitry Andric // -*- C++ -*- 2*0eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 3*0eae32dcSDimitry Andric // 4*0eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*0eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0eae32dcSDimitry Andric // 8*0eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 9*0eae32dcSDimitry Andric 10*0eae32dcSDimitry Andric #ifndef _LIBCPP___FILESYSTEM_PATH_H 11*0eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_PATH_H 12*0eae32dcSDimitry Andric 13*0eae32dcSDimitry Andric #include <__availability> 14*0eae32dcSDimitry Andric #include <__config> 15*0eae32dcSDimitry Andric #include <string> 16*0eae32dcSDimitry Andric #include <type_traits> 17*0eae32dcSDimitry Andric #include <__iterator/back_insert_iterator.h> 18*0eae32dcSDimitry Andric #include <__iterator/iterator_traits.h> 19*0eae32dcSDimitry Andric #include <cstddef> 20*0eae32dcSDimitry Andric #include <string_view> 21*0eae32dcSDimitry Andric 22*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 23*0eae32dcSDimitry Andric # include <locale> 24*0eae32dcSDimitry Andric # include <iomanip> // for quoted 25*0eae32dcSDimitry Andric #endif 26*0eae32dcSDimitry Andric 27*0eae32dcSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 28*0eae32dcSDimitry Andric 29*0eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM 30*0eae32dcSDimitry Andric 31*0eae32dcSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 32*0eae32dcSDimitry Andric 33*0eae32dcSDimitry Andric template <class _Tp> 34*0eae32dcSDimitry Andric struct __can_convert_char { 35*0eae32dcSDimitry Andric static const bool value = false; 36*0eae32dcSDimitry Andric }; 37*0eae32dcSDimitry Andric template <class _Tp> 38*0eae32dcSDimitry Andric struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {}; 39*0eae32dcSDimitry Andric template <> 40*0eae32dcSDimitry Andric struct __can_convert_char<char> { 41*0eae32dcSDimitry Andric static const bool value = true; 42*0eae32dcSDimitry Andric using __char_type = char; 43*0eae32dcSDimitry Andric }; 44*0eae32dcSDimitry Andric template <> 45*0eae32dcSDimitry Andric struct __can_convert_char<wchar_t> { 46*0eae32dcSDimitry Andric static const bool value = true; 47*0eae32dcSDimitry Andric using __char_type = wchar_t; 48*0eae32dcSDimitry Andric }; 49*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 50*0eae32dcSDimitry Andric template <> 51*0eae32dcSDimitry Andric struct __can_convert_char<char8_t> { 52*0eae32dcSDimitry Andric static const bool value = true; 53*0eae32dcSDimitry Andric using __char_type = char8_t; 54*0eae32dcSDimitry Andric }; 55*0eae32dcSDimitry Andric #endif 56*0eae32dcSDimitry Andric template <> 57*0eae32dcSDimitry Andric struct __can_convert_char<char16_t> { 58*0eae32dcSDimitry Andric static const bool value = true; 59*0eae32dcSDimitry Andric using __char_type = char16_t; 60*0eae32dcSDimitry Andric }; 61*0eae32dcSDimitry Andric template <> 62*0eae32dcSDimitry Andric struct __can_convert_char<char32_t> { 63*0eae32dcSDimitry Andric static const bool value = true; 64*0eae32dcSDimitry Andric using __char_type = char32_t; 65*0eae32dcSDimitry Andric }; 66*0eae32dcSDimitry Andric 67*0eae32dcSDimitry Andric template <class _ECharT> 68*0eae32dcSDimitry Andric typename enable_if<__can_convert_char<_ECharT>::value, bool>::type 69*0eae32dcSDimitry Andric __is_separator(_ECharT __e) { 70*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 71*0eae32dcSDimitry Andric return __e == _ECharT('/') || __e == _ECharT('\\'); 72*0eae32dcSDimitry Andric #else 73*0eae32dcSDimitry Andric return __e == _ECharT('/'); 74*0eae32dcSDimitry Andric #endif 75*0eae32dcSDimitry Andric } 76*0eae32dcSDimitry Andric 77*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 78*0eae32dcSDimitry Andric typedef u8string __u8_string; 79*0eae32dcSDimitry Andric #else 80*0eae32dcSDimitry Andric typedef string __u8_string; 81*0eae32dcSDimitry Andric #endif 82*0eae32dcSDimitry Andric 83*0eae32dcSDimitry Andric struct _NullSentinel {}; 84*0eae32dcSDimitry Andric 85*0eae32dcSDimitry Andric template <class _Tp> 86*0eae32dcSDimitry Andric using _Void = void; 87*0eae32dcSDimitry Andric 88*0eae32dcSDimitry Andric template <class _Tp, class = void> 89*0eae32dcSDimitry Andric struct __is_pathable_string : public false_type {}; 90*0eae32dcSDimitry Andric 91*0eae32dcSDimitry Andric template <class _ECharT, class _Traits, class _Alloc> 92*0eae32dcSDimitry Andric struct __is_pathable_string< 93*0eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Alloc>, 94*0eae32dcSDimitry Andric _Void<typename __can_convert_char<_ECharT>::__char_type> > 95*0eae32dcSDimitry Andric : public __can_convert_char<_ECharT> { 96*0eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Alloc>; 97*0eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 98*0eae32dcSDimitry Andric static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 99*0eae32dcSDimitry Andric static _ECharT const* __range_end(_Str const& __s) { 100*0eae32dcSDimitry Andric return __s.data() + __s.length(); 101*0eae32dcSDimitry Andric } 102*0eae32dcSDimitry Andric static _ECharT __first_or_null(_Str const& __s) { 103*0eae32dcSDimitry Andric return __s.empty() ? _ECharT{} : __s[0]; 104*0eae32dcSDimitry Andric } 105*0eae32dcSDimitry Andric }; 106*0eae32dcSDimitry Andric 107*0eae32dcSDimitry Andric template <class _ECharT, class _Traits> 108*0eae32dcSDimitry Andric struct __is_pathable_string< 109*0eae32dcSDimitry Andric basic_string_view<_ECharT, _Traits>, 110*0eae32dcSDimitry Andric _Void<typename __can_convert_char<_ECharT>::__char_type> > 111*0eae32dcSDimitry Andric : public __can_convert_char<_ECharT> { 112*0eae32dcSDimitry Andric using _Str = basic_string_view<_ECharT, _Traits>; 113*0eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 114*0eae32dcSDimitry Andric static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 115*0eae32dcSDimitry Andric static _ECharT const* __range_end(_Str const& __s) { 116*0eae32dcSDimitry Andric return __s.data() + __s.length(); 117*0eae32dcSDimitry Andric } 118*0eae32dcSDimitry Andric static _ECharT __first_or_null(_Str const& __s) { 119*0eae32dcSDimitry Andric return __s.empty() ? _ECharT{} : __s[0]; 120*0eae32dcSDimitry Andric } 121*0eae32dcSDimitry Andric }; 122*0eae32dcSDimitry Andric 123*0eae32dcSDimitry Andric template <class _Source, class _DS = typename decay<_Source>::type, 124*0eae32dcSDimitry Andric class _UnqualPtrType = 125*0eae32dcSDimitry Andric typename remove_const<typename remove_pointer<_DS>::type>::type, 126*0eae32dcSDimitry Andric bool _IsCharPtr = is_pointer<_DS>::value&& 127*0eae32dcSDimitry Andric __can_convert_char<_UnqualPtrType>::value> 128*0eae32dcSDimitry Andric struct __is_pathable_char_array : false_type {}; 129*0eae32dcSDimitry Andric 130*0eae32dcSDimitry Andric template <class _Source, class _ECharT, class _UPtr> 131*0eae32dcSDimitry Andric struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> 132*0eae32dcSDimitry Andric : __can_convert_char<typename remove_const<_ECharT>::type> { 133*0eae32dcSDimitry Andric using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; 134*0eae32dcSDimitry Andric 135*0eae32dcSDimitry Andric static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } 136*0eae32dcSDimitry Andric static _ECharT const* __range_end(const _ECharT* __b) { 137*0eae32dcSDimitry Andric using _Iter = const _ECharT*; 138*0eae32dcSDimitry Andric const _ECharT __sentinel = _ECharT{}; 139*0eae32dcSDimitry Andric _Iter __e = __b; 140*0eae32dcSDimitry Andric for (; *__e != __sentinel; ++__e) 141*0eae32dcSDimitry Andric ; 142*0eae32dcSDimitry Andric return __e; 143*0eae32dcSDimitry Andric } 144*0eae32dcSDimitry Andric 145*0eae32dcSDimitry Andric static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } 146*0eae32dcSDimitry Andric }; 147*0eae32dcSDimitry Andric 148*0eae32dcSDimitry Andric template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value, 149*0eae32dcSDimitry Andric class = void> 150*0eae32dcSDimitry Andric struct __is_pathable_iter : false_type {}; 151*0eae32dcSDimitry Andric 152*0eae32dcSDimitry Andric template <class _Iter> 153*0eae32dcSDimitry Andric struct __is_pathable_iter< 154*0eae32dcSDimitry Andric _Iter, true, 155*0eae32dcSDimitry Andric _Void<typename __can_convert_char< 156*0eae32dcSDimitry Andric typename iterator_traits<_Iter>::value_type>::__char_type> > 157*0eae32dcSDimitry Andric : __can_convert_char<typename iterator_traits<_Iter>::value_type> { 158*0eae32dcSDimitry Andric using _ECharT = typename iterator_traits<_Iter>::value_type; 159*0eae32dcSDimitry Andric using _Base = __can_convert_char<_ECharT>; 160*0eae32dcSDimitry Andric 161*0eae32dcSDimitry Andric static _Iter __range_begin(_Iter __b) { return __b; } 162*0eae32dcSDimitry Andric static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } 163*0eae32dcSDimitry Andric 164*0eae32dcSDimitry Andric static _ECharT __first_or_null(_Iter __b) { return *__b; } 165*0eae32dcSDimitry Andric }; 166*0eae32dcSDimitry Andric 167*0eae32dcSDimitry Andric template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, 168*0eae32dcSDimitry Andric bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, 169*0eae32dcSDimitry Andric bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> 170*0eae32dcSDimitry Andric struct __is_pathable : false_type { 171*0eae32dcSDimitry Andric static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); 172*0eae32dcSDimitry Andric }; 173*0eae32dcSDimitry Andric 174*0eae32dcSDimitry Andric template <class _Tp> 175*0eae32dcSDimitry Andric struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; 176*0eae32dcSDimitry Andric 177*0eae32dcSDimitry Andric template <class _Tp> 178*0eae32dcSDimitry Andric struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { 179*0eae32dcSDimitry Andric }; 180*0eae32dcSDimitry Andric 181*0eae32dcSDimitry Andric template <class _Tp> 182*0eae32dcSDimitry Andric struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; 183*0eae32dcSDimitry Andric 184*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 185*0eae32dcSDimitry Andric typedef wstring __path_string; 186*0eae32dcSDimitry Andric typedef wchar_t __path_value; 187*0eae32dcSDimitry Andric #else 188*0eae32dcSDimitry Andric typedef string __path_string; 189*0eae32dcSDimitry Andric typedef char __path_value; 190*0eae32dcSDimitry Andric #endif 191*0eae32dcSDimitry Andric 192*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 193*0eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 194*0eae32dcSDimitry Andric size_t __wide_to_char(const wstring&, char*, size_t); 195*0eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 196*0eae32dcSDimitry Andric size_t __char_to_wide(const string&, wchar_t*, size_t); 197*0eae32dcSDimitry Andric #endif 198*0eae32dcSDimitry Andric 199*0eae32dcSDimitry Andric template <class _ECharT> 200*0eae32dcSDimitry Andric struct _PathCVT; 201*0eae32dcSDimitry Andric 202*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 203*0eae32dcSDimitry Andric template <class _ECharT> 204*0eae32dcSDimitry Andric struct _PathCVT { 205*0eae32dcSDimitry Andric static_assert(__can_convert_char<_ECharT>::value, 206*0eae32dcSDimitry Andric "Char type not convertible"); 207*0eae32dcSDimitry Andric 208*0eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower; 209*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 210*0eae32dcSDimitry Andric typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener; 211*0eae32dcSDimitry Andric #endif 212*0eae32dcSDimitry Andric 213*0eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _ECharT const* __b, 214*0eae32dcSDimitry Andric _ECharT const* __e) { 215*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 216*0eae32dcSDimitry Andric string __utf8; 217*0eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __b, __e); 218*0eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 219*0eae32dcSDimitry Andric #else 220*0eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __b, __e); 221*0eae32dcSDimitry Andric #endif 222*0eae32dcSDimitry Andric } 223*0eae32dcSDimitry Andric 224*0eae32dcSDimitry Andric template <class _Iter> 225*0eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 226*0eae32dcSDimitry Andric static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 227*0eae32dcSDimitry Andric if (__b == __e) 228*0eae32dcSDimitry Andric return; 229*0eae32dcSDimitry Andric basic_string<_ECharT> __tmp(__b, __e); 230*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 231*0eae32dcSDimitry Andric string __utf8; 232*0eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __tmp.data(), 233*0eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 234*0eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 235*0eae32dcSDimitry Andric #else 236*0eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __tmp.data(), 237*0eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 238*0eae32dcSDimitry Andric #endif 239*0eae32dcSDimitry Andric } 240*0eae32dcSDimitry Andric 241*0eae32dcSDimitry Andric template <class _Iter> 242*0eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 243*0eae32dcSDimitry Andric static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 244*0eae32dcSDimitry Andric const _ECharT __sentinel = _ECharT{}; 245*0eae32dcSDimitry Andric if (*__b == __sentinel) 246*0eae32dcSDimitry Andric return; 247*0eae32dcSDimitry Andric basic_string<_ECharT> __tmp; 248*0eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 249*0eae32dcSDimitry Andric __tmp.push_back(*__b); 250*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 251*0eae32dcSDimitry Andric string __utf8; 252*0eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __tmp.data(), 253*0eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 254*0eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 255*0eae32dcSDimitry Andric #else 256*0eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __tmp.data(), 257*0eae32dcSDimitry Andric __tmp.data() + __tmp.length()); 258*0eae32dcSDimitry Andric #endif 259*0eae32dcSDimitry Andric } 260*0eae32dcSDimitry Andric 261*0eae32dcSDimitry Andric template <class _Source> 262*0eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 263*0eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 264*0eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 265*0eae32dcSDimitry Andric _Traits::__range_end(__s)); 266*0eae32dcSDimitry Andric } 267*0eae32dcSDimitry Andric }; 268*0eae32dcSDimitry Andric #endif // !_LIBCPP_HAS_NO_LOCALIZATION 269*0eae32dcSDimitry Andric 270*0eae32dcSDimitry Andric template <> 271*0eae32dcSDimitry Andric struct _PathCVT<__path_value> { 272*0eae32dcSDimitry Andric 273*0eae32dcSDimitry Andric template <class _Iter> 274*0eae32dcSDimitry Andric static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type 275*0eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 276*0eae32dcSDimitry Andric for (; __b != __e; ++__b) 277*0eae32dcSDimitry Andric __dest.push_back(*__b); 278*0eae32dcSDimitry Andric } 279*0eae32dcSDimitry Andric 280*0eae32dcSDimitry Andric template <class _Iter> 281*0eae32dcSDimitry Andric static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type 282*0eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 283*0eae32dcSDimitry Andric __dest.append(__b, __e); 284*0eae32dcSDimitry Andric } 285*0eae32dcSDimitry Andric 286*0eae32dcSDimitry Andric template <class _Iter> 287*0eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 288*0eae32dcSDimitry Andric const char __sentinel = char{}; 289*0eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 290*0eae32dcSDimitry Andric __dest.push_back(*__b); 291*0eae32dcSDimitry Andric } 292*0eae32dcSDimitry Andric 293*0eae32dcSDimitry Andric template <class _Source> 294*0eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 295*0eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 296*0eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 297*0eae32dcSDimitry Andric _Traits::__range_end(__s)); 298*0eae32dcSDimitry Andric } 299*0eae32dcSDimitry Andric }; 300*0eae32dcSDimitry Andric 301*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 302*0eae32dcSDimitry Andric template <> 303*0eae32dcSDimitry Andric struct _PathCVT<char> { 304*0eae32dcSDimitry Andric 305*0eae32dcSDimitry Andric static void 306*0eae32dcSDimitry Andric __append_string(__path_string& __dest, const basic_string<char> &__str) { 307*0eae32dcSDimitry Andric size_t __size = __char_to_wide(__str, nullptr, 0); 308*0eae32dcSDimitry Andric size_t __pos = __dest.size(); 309*0eae32dcSDimitry Andric __dest.resize(__pos + __size); 310*0eae32dcSDimitry Andric __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); 311*0eae32dcSDimitry Andric } 312*0eae32dcSDimitry Andric 313*0eae32dcSDimitry Andric template <class _Iter> 314*0eae32dcSDimitry Andric static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type 315*0eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 316*0eae32dcSDimitry Andric basic_string<char> __tmp(__b, __e); 317*0eae32dcSDimitry Andric __append_string(__dest, __tmp); 318*0eae32dcSDimitry Andric } 319*0eae32dcSDimitry Andric 320*0eae32dcSDimitry Andric template <class _Iter> 321*0eae32dcSDimitry Andric static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type 322*0eae32dcSDimitry Andric __append_range(__path_string& __dest, _Iter __b, _Iter __e) { 323*0eae32dcSDimitry Andric basic_string<char> __tmp(__b, __e); 324*0eae32dcSDimitry Andric __append_string(__dest, __tmp); 325*0eae32dcSDimitry Andric } 326*0eae32dcSDimitry Andric 327*0eae32dcSDimitry Andric template <class _Iter> 328*0eae32dcSDimitry Andric static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { 329*0eae32dcSDimitry Andric const char __sentinel = char{}; 330*0eae32dcSDimitry Andric basic_string<char> __tmp; 331*0eae32dcSDimitry Andric for (; *__b != __sentinel; ++__b) 332*0eae32dcSDimitry Andric __tmp.push_back(*__b); 333*0eae32dcSDimitry Andric __append_string(__dest, __tmp); 334*0eae32dcSDimitry Andric } 335*0eae32dcSDimitry Andric 336*0eae32dcSDimitry Andric template <class _Source> 337*0eae32dcSDimitry Andric static void __append_source(__path_string& __dest, _Source const& __s) { 338*0eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 339*0eae32dcSDimitry Andric __append_range(__dest, _Traits::__range_begin(__s), 340*0eae32dcSDimitry Andric _Traits::__range_end(__s)); 341*0eae32dcSDimitry Andric } 342*0eae32dcSDimitry Andric }; 343*0eae32dcSDimitry Andric 344*0eae32dcSDimitry Andric template <class _ECharT> 345*0eae32dcSDimitry Andric struct _PathExport { 346*0eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; 347*0eae32dcSDimitry Andric typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener; 348*0eae32dcSDimitry Andric 349*0eae32dcSDimitry Andric template <class _Str> 350*0eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 351*0eae32dcSDimitry Andric string __utf8; 352*0eae32dcSDimitry Andric _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); 353*0eae32dcSDimitry Andric _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); 354*0eae32dcSDimitry Andric } 355*0eae32dcSDimitry Andric }; 356*0eae32dcSDimitry Andric 357*0eae32dcSDimitry Andric template <> 358*0eae32dcSDimitry Andric struct _PathExport<char> { 359*0eae32dcSDimitry Andric template <class _Str> 360*0eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 361*0eae32dcSDimitry Andric size_t __size = __wide_to_char(__src, nullptr, 0); 362*0eae32dcSDimitry Andric size_t __pos = __dest.size(); 363*0eae32dcSDimitry Andric __dest.resize(__size); 364*0eae32dcSDimitry Andric __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size); 365*0eae32dcSDimitry Andric } 366*0eae32dcSDimitry Andric }; 367*0eae32dcSDimitry Andric 368*0eae32dcSDimitry Andric template <> 369*0eae32dcSDimitry Andric struct _PathExport<wchar_t> { 370*0eae32dcSDimitry Andric template <class _Str> 371*0eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 372*0eae32dcSDimitry Andric __dest.append(__src.begin(), __src.end()); 373*0eae32dcSDimitry Andric } 374*0eae32dcSDimitry Andric }; 375*0eae32dcSDimitry Andric 376*0eae32dcSDimitry Andric template <> 377*0eae32dcSDimitry Andric struct _PathExport<char16_t> { 378*0eae32dcSDimitry Andric template <class _Str> 379*0eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 380*0eae32dcSDimitry Andric __dest.append(__src.begin(), __src.end()); 381*0eae32dcSDimitry Andric } 382*0eae32dcSDimitry Andric }; 383*0eae32dcSDimitry Andric 384*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 385*0eae32dcSDimitry Andric template <> 386*0eae32dcSDimitry Andric struct _PathExport<char8_t> { 387*0eae32dcSDimitry Andric typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; 388*0eae32dcSDimitry Andric 389*0eae32dcSDimitry Andric template <class _Str> 390*0eae32dcSDimitry Andric static void __append(_Str& __dest, const __path_string& __src) { 391*0eae32dcSDimitry Andric _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); 392*0eae32dcSDimitry Andric } 393*0eae32dcSDimitry Andric }; 394*0eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_CHAR8_T */ 395*0eae32dcSDimitry Andric #endif /* _LIBCPP_WIN32API */ 396*0eae32dcSDimitry Andric 397*0eae32dcSDimitry Andric class _LIBCPP_TYPE_VIS path { 398*0eae32dcSDimitry Andric template <class _SourceOrIter, class _Tp = path&> 399*0eae32dcSDimitry Andric using _EnableIfPathable = 400*0eae32dcSDimitry Andric typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; 401*0eae32dcSDimitry Andric 402*0eae32dcSDimitry Andric template <class _Tp> 403*0eae32dcSDimitry Andric using _SourceChar = typename __is_pathable<_Tp>::__char_type; 404*0eae32dcSDimitry Andric 405*0eae32dcSDimitry Andric template <class _Tp> 406*0eae32dcSDimitry Andric using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; 407*0eae32dcSDimitry Andric 408*0eae32dcSDimitry Andric public: 409*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 410*0eae32dcSDimitry Andric typedef wchar_t value_type; 411*0eae32dcSDimitry Andric static constexpr value_type preferred_separator = L'\\'; 412*0eae32dcSDimitry Andric #else 413*0eae32dcSDimitry Andric typedef char value_type; 414*0eae32dcSDimitry Andric static constexpr value_type preferred_separator = '/'; 415*0eae32dcSDimitry Andric #endif 416*0eae32dcSDimitry Andric typedef basic_string<value_type> string_type; 417*0eae32dcSDimitry Andric typedef basic_string_view<value_type> __string_view; 418*0eae32dcSDimitry Andric 419*0eae32dcSDimitry Andric enum _LIBCPP_ENUM_VIS format : unsigned char { 420*0eae32dcSDimitry Andric auto_format, 421*0eae32dcSDimitry Andric native_format, 422*0eae32dcSDimitry Andric generic_format 423*0eae32dcSDimitry Andric }; 424*0eae32dcSDimitry Andric 425*0eae32dcSDimitry Andric // constructors and destructor 426*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path() noexcept {} 427*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {} 428*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept 429*0eae32dcSDimitry Andric : __pn_(_VSTD::move(__p.__pn_)) {} 430*0eae32dcSDimitry Andric 431*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 432*0eae32dcSDimitry Andric path(string_type&& __s, format = format::auto_format) noexcept 433*0eae32dcSDimitry Andric : __pn_(_VSTD::move(__s)) {} 434*0eae32dcSDimitry Andric 435*0eae32dcSDimitry Andric template <class _Source, class = _EnableIfPathable<_Source, void> > 436*0eae32dcSDimitry Andric path(const _Source& __src, format = format::auto_format) { 437*0eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __src); 438*0eae32dcSDimitry Andric } 439*0eae32dcSDimitry Andric 440*0eae32dcSDimitry Andric template <class _InputIt> 441*0eae32dcSDimitry Andric path(_InputIt __first, _InputIt __last, format = format::auto_format) { 442*0eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 443*0eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 444*0eae32dcSDimitry Andric } 445*0eae32dcSDimitry Andric 446*0eae32dcSDimitry Andric /* 447*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 448*0eae32dcSDimitry Andric // TODO Implement locale conversions. 449*0eae32dcSDimitry Andric template <class _Source, class = _EnableIfPathable<_Source, void> > 450*0eae32dcSDimitry Andric path(const _Source& __src, const locale& __loc, format = format::auto_format); 451*0eae32dcSDimitry Andric template <class _InputIt> 452*0eae32dcSDimitry Andric path(_InputIt __first, _InputIt _last, const locale& __loc, 453*0eae32dcSDimitry Andric format = format::auto_format); 454*0eae32dcSDimitry Andric #endif 455*0eae32dcSDimitry Andric */ 456*0eae32dcSDimitry Andric 457*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 458*0eae32dcSDimitry Andric ~path() = default; 459*0eae32dcSDimitry Andric 460*0eae32dcSDimitry Andric // assignments 461*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 462*0eae32dcSDimitry Andric path& operator=(const path& __p) { 463*0eae32dcSDimitry Andric __pn_ = __p.__pn_; 464*0eae32dcSDimitry Andric return *this; 465*0eae32dcSDimitry Andric } 466*0eae32dcSDimitry Andric 467*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 468*0eae32dcSDimitry Andric path& operator=(path&& __p) noexcept { 469*0eae32dcSDimitry Andric __pn_ = _VSTD::move(__p.__pn_); 470*0eae32dcSDimitry Andric return *this; 471*0eae32dcSDimitry Andric } 472*0eae32dcSDimitry Andric 473*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 474*0eae32dcSDimitry Andric path& operator=(string_type&& __s) noexcept { 475*0eae32dcSDimitry Andric __pn_ = _VSTD::move(__s); 476*0eae32dcSDimitry Andric return *this; 477*0eae32dcSDimitry Andric } 478*0eae32dcSDimitry Andric 479*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 480*0eae32dcSDimitry Andric path& assign(string_type&& __s) noexcept { 481*0eae32dcSDimitry Andric __pn_ = _VSTD::move(__s); 482*0eae32dcSDimitry Andric return *this; 483*0eae32dcSDimitry Andric } 484*0eae32dcSDimitry Andric 485*0eae32dcSDimitry Andric template <class _Source> 486*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 487*0eae32dcSDimitry Andric operator=(const _Source& __src) { 488*0eae32dcSDimitry Andric return this->assign(__src); 489*0eae32dcSDimitry Andric } 490*0eae32dcSDimitry Andric 491*0eae32dcSDimitry Andric template <class _Source> 492*0eae32dcSDimitry Andric _EnableIfPathable<_Source> assign(const _Source& __src) { 493*0eae32dcSDimitry Andric __pn_.clear(); 494*0eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __src); 495*0eae32dcSDimitry Andric return *this; 496*0eae32dcSDimitry Andric } 497*0eae32dcSDimitry Andric 498*0eae32dcSDimitry Andric template <class _InputIt> 499*0eae32dcSDimitry Andric path& assign(_InputIt __first, _InputIt __last) { 500*0eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 501*0eae32dcSDimitry Andric __pn_.clear(); 502*0eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 503*0eae32dcSDimitry Andric return *this; 504*0eae32dcSDimitry Andric } 505*0eae32dcSDimitry Andric 506*0eae32dcSDimitry Andric public: 507*0eae32dcSDimitry Andric // appends 508*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 509*0eae32dcSDimitry Andric path& operator/=(const path& __p) { 510*0eae32dcSDimitry Andric auto __p_root_name = __p.__root_name(); 511*0eae32dcSDimitry Andric auto __p_root_name_size = __p_root_name.size(); 512*0eae32dcSDimitry Andric if (__p.is_absolute() || 513*0eae32dcSDimitry Andric (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { 514*0eae32dcSDimitry Andric __pn_ = __p.__pn_; 515*0eae32dcSDimitry Andric return *this; 516*0eae32dcSDimitry Andric } 517*0eae32dcSDimitry Andric if (__p.has_root_directory()) { 518*0eae32dcSDimitry Andric path __root_name_str = root_name(); 519*0eae32dcSDimitry Andric __pn_ = __root_name_str.native(); 520*0eae32dcSDimitry Andric __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 521*0eae32dcSDimitry Andric return *this; 522*0eae32dcSDimitry Andric } 523*0eae32dcSDimitry Andric if (has_filename() || (!has_root_directory() && is_absolute())) 524*0eae32dcSDimitry Andric __pn_ += preferred_separator; 525*0eae32dcSDimitry Andric __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 526*0eae32dcSDimitry Andric return *this; 527*0eae32dcSDimitry Andric } 528*0eae32dcSDimitry Andric template <class _Source> 529*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 530*0eae32dcSDimitry Andric operator/=(const _Source& __src) { 531*0eae32dcSDimitry Andric return operator/=(path(__src)); 532*0eae32dcSDimitry Andric } 533*0eae32dcSDimitry Andric 534*0eae32dcSDimitry Andric template <class _Source> 535*0eae32dcSDimitry Andric _EnableIfPathable<_Source> append(const _Source& __src) { 536*0eae32dcSDimitry Andric return operator/=(path(__src)); 537*0eae32dcSDimitry Andric } 538*0eae32dcSDimitry Andric 539*0eae32dcSDimitry Andric template <class _InputIt> 540*0eae32dcSDimitry Andric path& append(_InputIt __first, _InputIt __last) { 541*0eae32dcSDimitry Andric return operator/=(path(__first, __last)); 542*0eae32dcSDimitry Andric } 543*0eae32dcSDimitry Andric #else 544*0eae32dcSDimitry Andric path& operator/=(const path& __p) { 545*0eae32dcSDimitry Andric if (__p.is_absolute()) { 546*0eae32dcSDimitry Andric __pn_ = __p.__pn_; 547*0eae32dcSDimitry Andric return *this; 548*0eae32dcSDimitry Andric } 549*0eae32dcSDimitry Andric if (has_filename()) 550*0eae32dcSDimitry Andric __pn_ += preferred_separator; 551*0eae32dcSDimitry Andric __pn_ += __p.native(); 552*0eae32dcSDimitry Andric return *this; 553*0eae32dcSDimitry Andric } 554*0eae32dcSDimitry Andric 555*0eae32dcSDimitry Andric // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src 556*0eae32dcSDimitry Andric // is known at compile time to be "/' since the user almost certainly intended 557*0eae32dcSDimitry Andric // to append a separator instead of overwriting the path with "/" 558*0eae32dcSDimitry Andric template <class _Source> 559*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 560*0eae32dcSDimitry Andric operator/=(const _Source& __src) { 561*0eae32dcSDimitry Andric return this->append(__src); 562*0eae32dcSDimitry Andric } 563*0eae32dcSDimitry Andric 564*0eae32dcSDimitry Andric template <class _Source> 565*0eae32dcSDimitry Andric _EnableIfPathable<_Source> append(const _Source& __src) { 566*0eae32dcSDimitry Andric using _Traits = __is_pathable<_Source>; 567*0eae32dcSDimitry Andric using _CVT = _PathCVT<_SourceChar<_Source> >; 568*0eae32dcSDimitry Andric bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src)); 569*0eae32dcSDimitry Andric if (__source_is_absolute) 570*0eae32dcSDimitry Andric __pn_.clear(); 571*0eae32dcSDimitry Andric else if (has_filename()) 572*0eae32dcSDimitry Andric __pn_ += preferred_separator; 573*0eae32dcSDimitry Andric _CVT::__append_source(__pn_, __src); 574*0eae32dcSDimitry Andric return *this; 575*0eae32dcSDimitry Andric } 576*0eae32dcSDimitry Andric 577*0eae32dcSDimitry Andric template <class _InputIt> 578*0eae32dcSDimitry Andric path& append(_InputIt __first, _InputIt __last) { 579*0eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 580*0eae32dcSDimitry Andric static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); 581*0eae32dcSDimitry Andric using _CVT = _PathCVT<_ItVal>; 582*0eae32dcSDimitry Andric if (__first != __last && __is_separator(*__first)) 583*0eae32dcSDimitry Andric __pn_.clear(); 584*0eae32dcSDimitry Andric else if (has_filename()) 585*0eae32dcSDimitry Andric __pn_ += preferred_separator; 586*0eae32dcSDimitry Andric _CVT::__append_range(__pn_, __first, __last); 587*0eae32dcSDimitry Andric return *this; 588*0eae32dcSDimitry Andric } 589*0eae32dcSDimitry Andric #endif 590*0eae32dcSDimitry Andric 591*0eae32dcSDimitry Andric // concatenation 592*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 593*0eae32dcSDimitry Andric path& operator+=(const path& __x) { 594*0eae32dcSDimitry Andric __pn_ += __x.__pn_; 595*0eae32dcSDimitry Andric return *this; 596*0eae32dcSDimitry Andric } 597*0eae32dcSDimitry Andric 598*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 599*0eae32dcSDimitry Andric path& operator+=(const string_type& __x) { 600*0eae32dcSDimitry Andric __pn_ += __x; 601*0eae32dcSDimitry Andric return *this; 602*0eae32dcSDimitry Andric } 603*0eae32dcSDimitry Andric 604*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 605*0eae32dcSDimitry Andric path& operator+=(__string_view __x) { 606*0eae32dcSDimitry Andric __pn_ += __x; 607*0eae32dcSDimitry Andric return *this; 608*0eae32dcSDimitry Andric } 609*0eae32dcSDimitry Andric 610*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 611*0eae32dcSDimitry Andric path& operator+=(const value_type* __x) { 612*0eae32dcSDimitry Andric __pn_ += __x; 613*0eae32dcSDimitry Andric return *this; 614*0eae32dcSDimitry Andric } 615*0eae32dcSDimitry Andric 616*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 617*0eae32dcSDimitry Andric path& operator+=(value_type __x) { 618*0eae32dcSDimitry Andric __pn_ += __x; 619*0eae32dcSDimitry Andric return *this; 620*0eae32dcSDimitry Andric } 621*0eae32dcSDimitry Andric 622*0eae32dcSDimitry Andric template <class _ECharT> 623*0eae32dcSDimitry Andric typename enable_if<__can_convert_char<_ECharT>::value, path&>::type 624*0eae32dcSDimitry Andric operator+=(_ECharT __x) { 625*0eae32dcSDimitry Andric _PathCVT<_ECharT>::__append_source(__pn_, 626*0eae32dcSDimitry Andric basic_string_view<_ECharT>(&__x, 1)); 627*0eae32dcSDimitry Andric return *this; 628*0eae32dcSDimitry Andric } 629*0eae32dcSDimitry Andric 630*0eae32dcSDimitry Andric template <class _Source> 631*0eae32dcSDimitry Andric _EnableIfPathable<_Source> operator+=(const _Source& __x) { 632*0eae32dcSDimitry Andric return this->concat(__x); 633*0eae32dcSDimitry Andric } 634*0eae32dcSDimitry Andric 635*0eae32dcSDimitry Andric template <class _Source> 636*0eae32dcSDimitry Andric _EnableIfPathable<_Source> concat(const _Source& __x) { 637*0eae32dcSDimitry Andric _SourceCVT<_Source>::__append_source(__pn_, __x); 638*0eae32dcSDimitry Andric return *this; 639*0eae32dcSDimitry Andric } 640*0eae32dcSDimitry Andric 641*0eae32dcSDimitry Andric template <class _InputIt> 642*0eae32dcSDimitry Andric path& concat(_InputIt __first, _InputIt __last) { 643*0eae32dcSDimitry Andric typedef typename iterator_traits<_InputIt>::value_type _ItVal; 644*0eae32dcSDimitry Andric _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 645*0eae32dcSDimitry Andric return *this; 646*0eae32dcSDimitry Andric } 647*0eae32dcSDimitry Andric 648*0eae32dcSDimitry Andric // modifiers 649*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 650*0eae32dcSDimitry Andric void clear() noexcept { __pn_.clear(); } 651*0eae32dcSDimitry Andric 652*0eae32dcSDimitry Andric path& make_preferred() { 653*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 654*0eae32dcSDimitry Andric _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); 655*0eae32dcSDimitry Andric #endif 656*0eae32dcSDimitry Andric return *this; 657*0eae32dcSDimitry Andric } 658*0eae32dcSDimitry Andric 659*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 660*0eae32dcSDimitry Andric path& remove_filename() { 661*0eae32dcSDimitry Andric auto __fname = __filename(); 662*0eae32dcSDimitry Andric if (!__fname.empty()) 663*0eae32dcSDimitry Andric __pn_.erase(__fname.data() - __pn_.data()); 664*0eae32dcSDimitry Andric return *this; 665*0eae32dcSDimitry Andric } 666*0eae32dcSDimitry Andric 667*0eae32dcSDimitry Andric path& replace_filename(const path& __replacement) { 668*0eae32dcSDimitry Andric remove_filename(); 669*0eae32dcSDimitry Andric return (*this /= __replacement); 670*0eae32dcSDimitry Andric } 671*0eae32dcSDimitry Andric 672*0eae32dcSDimitry Andric path& replace_extension(const path& __replacement = path()); 673*0eae32dcSDimitry Andric 674*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 675*0eae32dcSDimitry Andric void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } 676*0eae32dcSDimitry Andric 677*0eae32dcSDimitry Andric // private helper to allow reserving memory in the path 678*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 679*0eae32dcSDimitry Andric void __reserve(size_t __s) { __pn_.reserve(__s); } 680*0eae32dcSDimitry Andric 681*0eae32dcSDimitry Andric // native format observers 682*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 683*0eae32dcSDimitry Andric const string_type& native() const noexcept { return __pn_; } 684*0eae32dcSDimitry Andric 685*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY 686*0eae32dcSDimitry Andric const value_type* c_str() const noexcept { return __pn_.c_str(); } 687*0eae32dcSDimitry Andric 688*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } 689*0eae32dcSDimitry Andric 690*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 691*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; } 692*0eae32dcSDimitry Andric 693*0eae32dcSDimitry Andric _VSTD::wstring generic_wstring() const { 694*0eae32dcSDimitry Andric _VSTD::wstring __s; 695*0eae32dcSDimitry Andric __s.resize(__pn_.size()); 696*0eae32dcSDimitry Andric _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); 697*0eae32dcSDimitry Andric return __s; 698*0eae32dcSDimitry Andric } 699*0eae32dcSDimitry Andric 700*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 701*0eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 702*0eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 703*0eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 704*0eae32dcSDimitry Andric string(const _Allocator& __a = _Allocator()) const { 705*0eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 706*0eae32dcSDimitry Andric _Str __s(__a); 707*0eae32dcSDimitry Andric __s.reserve(__pn_.size()); 708*0eae32dcSDimitry Andric _PathExport<_ECharT>::__append(__s, __pn_); 709*0eae32dcSDimitry Andric return __s; 710*0eae32dcSDimitry Andric } 711*0eae32dcSDimitry Andric 712*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { 713*0eae32dcSDimitry Andric return string<char>(); 714*0eae32dcSDimitry Andric } 715*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const { 716*0eae32dcSDimitry Andric using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 717*0eae32dcSDimitry Andric __u8_string __s; 718*0eae32dcSDimitry Andric __s.reserve(__pn_.size()); 719*0eae32dcSDimitry Andric _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 720*0eae32dcSDimitry Andric return __s; 721*0eae32dcSDimitry Andric } 722*0eae32dcSDimitry Andric 723*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { 724*0eae32dcSDimitry Andric return string<char16_t>(); 725*0eae32dcSDimitry Andric } 726*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { 727*0eae32dcSDimitry Andric return string<char32_t>(); 728*0eae32dcSDimitry Andric } 729*0eae32dcSDimitry Andric 730*0eae32dcSDimitry Andric // generic format observers 731*0eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 732*0eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 733*0eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 734*0eae32dcSDimitry Andric generic_string(const _Allocator& __a = _Allocator()) const { 735*0eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 736*0eae32dcSDimitry Andric _Str __s = string<_ECharT, _Traits, _Allocator>(__a); 737*0eae32dcSDimitry Andric // Note: This (and generic_u8string below) is slightly suboptimal as 738*0eae32dcSDimitry Andric // it iterates twice over the string; once to convert it to the right 739*0eae32dcSDimitry Andric // character type, and once to replace path delimiters. 740*0eae32dcSDimitry Andric _VSTD::replace(__s.begin(), __s.end(), 741*0eae32dcSDimitry Andric static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); 742*0eae32dcSDimitry Andric return __s; 743*0eae32dcSDimitry Andric } 744*0eae32dcSDimitry Andric 745*0eae32dcSDimitry Andric _VSTD::string generic_string() const { return generic_string<char>(); } 746*0eae32dcSDimitry Andric _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); } 747*0eae32dcSDimitry Andric _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); } 748*0eae32dcSDimitry Andric __u8_string generic_u8string() const { 749*0eae32dcSDimitry Andric __u8_string __s = u8string(); 750*0eae32dcSDimitry Andric _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); 751*0eae32dcSDimitry Andric return __s; 752*0eae32dcSDimitry Andric } 753*0eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 754*0eae32dcSDimitry Andric #else /* _LIBCPP_WIN32API */ 755*0eae32dcSDimitry Andric 756*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; } 757*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 758*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 759*0eae32dcSDimitry Andric #else 760*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; } 761*0eae32dcSDimitry Andric #endif 762*0eae32dcSDimitry Andric 763*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 764*0eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 765*0eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 766*0eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 767*0eae32dcSDimitry Andric string(const _Allocator& __a = _Allocator()) const { 768*0eae32dcSDimitry Andric using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>; 769*0eae32dcSDimitry Andric using _Str = basic_string<_ECharT, _Traits, _Allocator>; 770*0eae32dcSDimitry Andric _Str __s(__a); 771*0eae32dcSDimitry Andric __s.reserve(__pn_.size()); 772*0eae32dcSDimitry Andric _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 773*0eae32dcSDimitry Andric return __s; 774*0eae32dcSDimitry Andric } 775*0eae32dcSDimitry Andric 776*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 777*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { 778*0eae32dcSDimitry Andric return string<wchar_t>(); 779*0eae32dcSDimitry Andric } 780*0eae32dcSDimitry Andric #endif 781*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { 782*0eae32dcSDimitry Andric return string<char16_t>(); 783*0eae32dcSDimitry Andric } 784*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { 785*0eae32dcSDimitry Andric return string<char32_t>(); 786*0eae32dcSDimitry Andric } 787*0eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 788*0eae32dcSDimitry Andric 789*0eae32dcSDimitry Andric // generic format observers 790*0eae32dcSDimitry Andric _VSTD::string generic_string() const { return __pn_; } 791*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 792*0eae32dcSDimitry Andric _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 793*0eae32dcSDimitry Andric #else 794*0eae32dcSDimitry Andric _VSTD::string generic_u8string() const { return __pn_; } 795*0eae32dcSDimitry Andric #endif 796*0eae32dcSDimitry Andric 797*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 798*0eae32dcSDimitry Andric template <class _ECharT, class _Traits = char_traits<_ECharT>, 799*0eae32dcSDimitry Andric class _Allocator = allocator<_ECharT> > 800*0eae32dcSDimitry Andric basic_string<_ECharT, _Traits, _Allocator> 801*0eae32dcSDimitry Andric generic_string(const _Allocator& __a = _Allocator()) const { 802*0eae32dcSDimitry Andric return string<_ECharT, _Traits, _Allocator>(__a); 803*0eae32dcSDimitry Andric } 804*0eae32dcSDimitry Andric 805*0eae32dcSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 806*0eae32dcSDimitry Andric _VSTD::wstring generic_wstring() const { return string<wchar_t>(); } 807*0eae32dcSDimitry Andric #endif 808*0eae32dcSDimitry Andric _VSTD::u16string generic_u16string() const { return string<char16_t>(); } 809*0eae32dcSDimitry Andric _VSTD::u32string generic_u32string() const { return string<char32_t>(); } 810*0eae32dcSDimitry Andric #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 811*0eae32dcSDimitry Andric #endif /* !_LIBCPP_WIN32API */ 812*0eae32dcSDimitry Andric 813*0eae32dcSDimitry Andric private: 814*0eae32dcSDimitry Andric int __compare(__string_view) const; 815*0eae32dcSDimitry Andric __string_view __root_name() const; 816*0eae32dcSDimitry Andric __string_view __root_directory() const; 817*0eae32dcSDimitry Andric __string_view __root_path_raw() const; 818*0eae32dcSDimitry Andric __string_view __relative_path() const; 819*0eae32dcSDimitry Andric __string_view __parent_path() const; 820*0eae32dcSDimitry Andric __string_view __filename() const; 821*0eae32dcSDimitry Andric __string_view __stem() const; 822*0eae32dcSDimitry Andric __string_view __extension() const; 823*0eae32dcSDimitry Andric 824*0eae32dcSDimitry Andric public: 825*0eae32dcSDimitry Andric // compare 826*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept { 827*0eae32dcSDimitry Andric return __compare(__p.__pn_); 828*0eae32dcSDimitry Andric } 829*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { 830*0eae32dcSDimitry Andric return __compare(__s); 831*0eae32dcSDimitry Andric } 832*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { 833*0eae32dcSDimitry Andric return __compare(__s); 834*0eae32dcSDimitry Andric } 835*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { 836*0eae32dcSDimitry Andric return __compare(__s); 837*0eae32dcSDimitry Andric } 838*0eae32dcSDimitry Andric 839*0eae32dcSDimitry Andric // decomposition 840*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path root_name() const { 841*0eae32dcSDimitry Andric return string_type(__root_name()); 842*0eae32dcSDimitry Andric } 843*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path root_directory() const { 844*0eae32dcSDimitry Andric return string_type(__root_directory()); 845*0eae32dcSDimitry Andric } 846*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path root_path() const { 847*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 848*0eae32dcSDimitry Andric return string_type(__root_path_raw()); 849*0eae32dcSDimitry Andric #else 850*0eae32dcSDimitry Andric return root_name().append(string_type(__root_directory())); 851*0eae32dcSDimitry Andric #endif 852*0eae32dcSDimitry Andric } 853*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path relative_path() const { 854*0eae32dcSDimitry Andric return string_type(__relative_path()); 855*0eae32dcSDimitry Andric } 856*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path parent_path() const { 857*0eae32dcSDimitry Andric return string_type(__parent_path()); 858*0eae32dcSDimitry Andric } 859*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path filename() const { 860*0eae32dcSDimitry Andric return string_type(__filename()); 861*0eae32dcSDimitry Andric } 862*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); } 863*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path extension() const { 864*0eae32dcSDimitry Andric return string_type(__extension()); 865*0eae32dcSDimitry Andric } 866*0eae32dcSDimitry Andric 867*0eae32dcSDimitry Andric // query 868*0eae32dcSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool 869*0eae32dcSDimitry Andric empty() const noexcept { 870*0eae32dcSDimitry Andric return __pn_.empty(); 871*0eae32dcSDimitry Andric } 872*0eae32dcSDimitry Andric 873*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { 874*0eae32dcSDimitry Andric return !__root_name().empty(); 875*0eae32dcSDimitry Andric } 876*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { 877*0eae32dcSDimitry Andric return !__root_directory().empty(); 878*0eae32dcSDimitry Andric } 879*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { 880*0eae32dcSDimitry Andric return !__root_path_raw().empty(); 881*0eae32dcSDimitry Andric } 882*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { 883*0eae32dcSDimitry Andric return !__relative_path().empty(); 884*0eae32dcSDimitry Andric } 885*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { 886*0eae32dcSDimitry Andric return !__parent_path().empty(); 887*0eae32dcSDimitry Andric } 888*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_filename() const { 889*0eae32dcSDimitry Andric return !__filename().empty(); 890*0eae32dcSDimitry Andric } 891*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } 892*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool has_extension() const { 893*0eae32dcSDimitry Andric return !__extension().empty(); 894*0eae32dcSDimitry Andric } 895*0eae32dcSDimitry Andric 896*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { 897*0eae32dcSDimitry Andric #if defined(_LIBCPP_WIN32API) 898*0eae32dcSDimitry Andric __string_view __root_name_str = __root_name(); 899*0eae32dcSDimitry Andric __string_view __root_dir = __root_directory(); 900*0eae32dcSDimitry Andric if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { 901*0eae32dcSDimitry Andric // A drive letter with no root directory is relative, e.g. x:example. 902*0eae32dcSDimitry Andric return !__root_dir.empty(); 903*0eae32dcSDimitry Andric } 904*0eae32dcSDimitry Andric // If no root name, it's relative, e.g. \example is relative to the current drive 905*0eae32dcSDimitry Andric if (__root_name_str.empty()) 906*0eae32dcSDimitry Andric return false; 907*0eae32dcSDimitry Andric if (__root_name_str.size() < 3) 908*0eae32dcSDimitry Andric return false; 909*0eae32dcSDimitry Andric // A server root name, like \\server, is always absolute 910*0eae32dcSDimitry Andric if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') 911*0eae32dcSDimitry Andric return false; 912*0eae32dcSDimitry Andric if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') 913*0eae32dcSDimitry Andric return false; 914*0eae32dcSDimitry Andric // Seems to be a server root name 915*0eae32dcSDimitry Andric return true; 916*0eae32dcSDimitry Andric #else 917*0eae32dcSDimitry Andric return has_root_directory(); 918*0eae32dcSDimitry Andric #endif 919*0eae32dcSDimitry Andric } 920*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } 921*0eae32dcSDimitry Andric 922*0eae32dcSDimitry Andric // relative paths 923*0eae32dcSDimitry Andric path lexically_normal() const; 924*0eae32dcSDimitry Andric path lexically_relative(const path& __base) const; 925*0eae32dcSDimitry Andric 926*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const { 927*0eae32dcSDimitry Andric path __result = this->lexically_relative(__base); 928*0eae32dcSDimitry Andric if (__result.native().empty()) 929*0eae32dcSDimitry Andric return *this; 930*0eae32dcSDimitry Andric return __result; 931*0eae32dcSDimitry Andric } 932*0eae32dcSDimitry Andric 933*0eae32dcSDimitry Andric // iterators 934*0eae32dcSDimitry Andric class _LIBCPP_TYPE_VIS iterator; 935*0eae32dcSDimitry Andric typedef iterator const_iterator; 936*0eae32dcSDimitry Andric 937*0eae32dcSDimitry Andric iterator begin() const; 938*0eae32dcSDimitry Andric iterator end() const; 939*0eae32dcSDimitry Andric 940*0eae32dcSDimitry Andric #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 941*0eae32dcSDimitry Andric template <class _CharT, class _Traits> 942*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend 943*0eae32dcSDimitry Andric typename enable_if<is_same<_CharT, value_type>::value && 944*0eae32dcSDimitry Andric is_same<_Traits, char_traits<value_type> >::value, 945*0eae32dcSDimitry Andric basic_ostream<_CharT, _Traits>&>::type 946*0eae32dcSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 947*0eae32dcSDimitry Andric __os << _VSTD::__quoted(__p.native()); 948*0eae32dcSDimitry Andric return __os; 949*0eae32dcSDimitry Andric } 950*0eae32dcSDimitry Andric 951*0eae32dcSDimitry Andric template <class _CharT, class _Traits> 952*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend 953*0eae32dcSDimitry Andric typename enable_if<!is_same<_CharT, value_type>::value || 954*0eae32dcSDimitry Andric !is_same<_Traits, char_traits<value_type> >::value, 955*0eae32dcSDimitry Andric basic_ostream<_CharT, _Traits>&>::type 956*0eae32dcSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 957*0eae32dcSDimitry Andric __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); 958*0eae32dcSDimitry Andric return __os; 959*0eae32dcSDimitry Andric } 960*0eae32dcSDimitry Andric 961*0eae32dcSDimitry Andric template <class _CharT, class _Traits> 962*0eae32dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& 963*0eae32dcSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { 964*0eae32dcSDimitry Andric basic_string<_CharT, _Traits> __tmp; 965*0eae32dcSDimitry Andric __is >> __quoted(__tmp); 966*0eae32dcSDimitry Andric __p = __tmp; 967*0eae32dcSDimitry Andric return __is; 968*0eae32dcSDimitry Andric } 969*0eae32dcSDimitry Andric #endif // !_LIBCPP_HAS_NO_LOCALIZATION 970*0eae32dcSDimitry Andric 971*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { 972*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) == 0; 973*0eae32dcSDimitry Andric } 974*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { 975*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) != 0; 976*0eae32dcSDimitry Andric } 977*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { 978*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) < 0; 979*0eae32dcSDimitry Andric } 980*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { 981*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) <= 0; 982*0eae32dcSDimitry Andric } 983*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { 984*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) > 0; 985*0eae32dcSDimitry Andric } 986*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { 987*0eae32dcSDimitry Andric return __lhs.__compare(__rhs.__pn_) >= 0; 988*0eae32dcSDimitry Andric } 989*0eae32dcSDimitry Andric 990*0eae32dcSDimitry Andric friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, 991*0eae32dcSDimitry Andric const path& __rhs) { 992*0eae32dcSDimitry Andric path __result(__lhs); 993*0eae32dcSDimitry Andric __result /= __rhs; 994*0eae32dcSDimitry Andric return __result; 995*0eae32dcSDimitry Andric } 996*0eae32dcSDimitry Andric private: 997*0eae32dcSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY path& 998*0eae32dcSDimitry Andric __assign_view(__string_view const& __s) noexcept { 999*0eae32dcSDimitry Andric __pn_ = string_type(__s); 1000*0eae32dcSDimitry Andric return *this; 1001*0eae32dcSDimitry Andric } 1002*0eae32dcSDimitry Andric string_type __pn_; 1003*0eae32dcSDimitry Andric }; 1004*0eae32dcSDimitry Andric 1005*0eae32dcSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { 1006*0eae32dcSDimitry Andric __lhs.swap(__rhs); 1007*0eae32dcSDimitry Andric } 1008*0eae32dcSDimitry Andric 1009*0eae32dcSDimitry Andric _LIBCPP_FUNC_VIS 1010*0eae32dcSDimitry Andric size_t hash_value(const path& __p) noexcept; 1011*0eae32dcSDimitry Andric 1012*0eae32dcSDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_POP 1013*0eae32dcSDimitry Andric 1014*0eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM 1015*0eae32dcSDimitry Andric 1016*0eae32dcSDimitry Andric #endif // _LIBCPP_CXX03_LANG 1017*0eae32dcSDimitry Andric 1018*0eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_PATH_H 1019