1313#include < __algorithm/unwrap_iter.h>
1414#include < __config>
1515#include < __filesystem/path.h>
16-
17- #if _LIBCPP_HAS_LOCALIZATION
18- #include < __locale>
16+ #if !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
17+ # include < __locale>
1918#endif
2019#include < string>
2120
2726
2827_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2928
30- # if !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
31- template <class _InputIt , __enable_if_t <__is_pathable<_InputIt>::value, int > = 0 >
32- _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path (_InputIt __f, _InputIt __l) {
29+ # if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
30+ # define _LIBCPP_FS_U8PATH_CONVERTS_ENCODING 1
31+ # else
32+ # define _LIBCPP_FS_U8PATH_CONVERTS_ENCODING 0
33+ # endif
34+
35+ # if _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
36+ template <class _InputIt , class _Sentinel >
37+ _LIBCPP_HIDE_FROM_ABI string __make_tmp_string_for_u8path (_InputIt __f, _Sentinel __l) {
38+ static_assert (__is_pathable<_InputIt>::value);
3339 static_assert (
3440# if _LIBCPP_HAS_CHAR8_T
35- is_same<typename __is_pathable<_InputIt>::__char_type, char8_t >::value ||
41+ is_same<typename __is_pathable<_InputIt>::__char_type, char8_t >::value ||
3642# endif
37- is_same<typename __is_pathable<_InputIt>::__char_type, char >::value,
38- " u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
39- " or 'char8_t'" );
40- # if defined(_LIBCPP_WIN32API)
41- string __tmp (__f, __l);
42- using _CVT = __widen_from_utf8<sizeof (wchar_t ) * __CHAR_BIT__>;
43- std::wstring __w;
44- __w.reserve (__tmp.size ());
45- _CVT ()(back_inserter (__w), __tmp.data (), __tmp.data () + __tmp.size ());
46- return path (__w);
47- # else
48- return path (__f, __l);
49- # endif /* !_LIBCPP_WIN32API */
43+ is_same<typename __is_pathable<_InputIt>::__char_type, char >::value);
44+
45+ if constexpr (is_same_v<_Sentinel, _NullSentinel>) {
46+ string __tmp;
47+ constexpr char __sentinel{};
48+ for (; *__f != __sentinel; ++__f)
49+ __tmp.push_back (*__f);
50+ return __tmp;
51+ } else {
52+ static_assert (is_same_v<_InputIt, _Sentinel>);
53+ return string (__f, __l);
54+ }
55+ }
56+ # endif // _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
57+
58+ template <class _InputIt , class _Sentinel >
59+ _LIBCPP_HIDE_FROM_ABI path __u8path (_InputIt __f, _Sentinel __l) {
60+ # if _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
61+ auto __tmp = std::filesystem::__make_tmp_string_for_u8path (__f, __l);
62+ using _CVT = __widen_from_utf8<sizeof (wchar_t ) * __CHAR_BIT__>;
63+ std::wstring __w;
64+ __w.reserve (__tmp.size ());
65+ _CVT ()(back_inserter (__w), __tmp.data (), __tmp.data () + __tmp.size ());
66+ return path (__w);
67+ # else
68+ return path (__f, __l);
69+ # endif // _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
5070}
51- # endif /* !_LIBCPP_WIN32API || _LIBCPP_HAS_LOCALIZATION */
5271
53- # if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
5472template <class _InputIt , __enable_if_t <__is_pathable<_InputIt>::value, int > = 0 >
55- _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path (_InputIt __f, _NullSentinel ) {
73+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path (_InputIt __f, _InputIt __l ) {
5674 static_assert (
57- # if _LIBCPP_HAS_CHAR8_T
75+ # if _LIBCPP_HAS_CHAR8_T
5876 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t >::value ||
59- # endif
77+ # endif
6078 is_same<typename __is_pathable<_InputIt>::__char_type, char >::value,
6179 " u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
6280 " or 'char8_t'" );
63- string __tmp;
64- const char __sentinel = char {};
65- for (; *__f != __sentinel; ++__f)
66- __tmp.push_back (*__f);
67- using _CVT = __widen_from_utf8<sizeof (wchar_t ) * __CHAR_BIT__>;
68- std::wstring __w;
69- __w.reserve (__tmp.size ());
70- _CVT ()(back_inserter (__w), __tmp.data (), __tmp.data () + __tmp.size ());
71- return path (__w);
81+ return std::filesystem::__u8path (__f, __l);
7282}
73- # endif /* _LIBCPP_WIN32API && _LIBCPP_HAS_LOCALIZATION */
7483
7584template <class _Source , __enable_if_t <__is_pathable<_Source>::value, int > = 0 >
7685_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path (const _Source& __s) {
@@ -81,15 +90,19 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source&
8190 is_same<typename __is_pathable<_Source>::__char_type, char >::value,
8291 " u8path(Source const&) requires Source have a character type of type "
8392 " 'char' or 'char8_t'" );
84- # if defined(_LIBCPP_WIN32API)
93+ # if _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
8594 using _Traits = __is_pathable<_Source>;
86- return u8path (std::__unwrap_iter (_Traits::__range_begin (__s)), std::__unwrap_iter (_Traits::__range_end (__s)));
95+ return std::filesystem::__u8path (
96+ std::__unwrap_iter (_Traits::__range_begin (__s)), std::__unwrap_iter (_Traits::__range_end (__s)));
8797# else
8898 return path (__s);
89- # endif
99+ # endif // _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
90100}
91101
102+ # undef _LIBCPP_FS_U8PATH_CONVERTS_ENCODING
103+
92104_LIBCPP_END_NAMESPACE_FILESYSTEM
105+
93106#endif // _LIBCPP_STD_VER >= 17
94107
95108#endif // _LIBCPP___FILESYSTEM_U8PATH_H
0 commit comments