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