1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___FILESYSTEM_U8PATH_H |
11 | #define _LIBCPP___FILESYSTEM_U8PATH_H |
12 | |
13 | #include <__algorithm/unwrap_iter.h> |
14 | #include <__config> |
15 | #include <__filesystem/path.h> |
16 | #include <string> |
17 | |
18 | // Only required on Windows for __widen_from_utf8, and included conservatively |
19 | // because it requires support for localization. |
20 | #if defined(_LIBCPP_WIN32API) |
21 | # include <locale> |
22 | #endif |
23 | |
24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
25 | # pragma GCC system_header |
26 | #endif |
27 | |
28 | #if _LIBCPP_STD_VER >= 17 |
29 | |
30 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
31 | |
32 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH |
33 | |
34 | template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0> |
35 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) { |
36 | static_assert( |
37 | # ifndef _LIBCPP_HAS_NO_CHAR8_T |
38 | is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || |
39 | # endif |
40 | is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, |
41 | "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" |
42 | " or 'char8_t'" ); |
43 | # if defined(_LIBCPP_WIN32API) |
44 | string __tmp(__f, __l); |
45 | using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; |
46 | std::wstring __w; |
47 | __w.reserve(__tmp.size()); |
48 | _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); |
49 | return path(__w); |
50 | # else |
51 | return path(__f, __l); |
52 | # endif /* !_LIBCPP_WIN32API */ |
53 | } |
54 | |
55 | # if defined(_LIBCPP_WIN32API) |
56 | template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0> |
57 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) { |
58 | static_assert( |
59 | # ifndef _LIBCPP_HAS_NO_CHAR8_T |
60 | is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || |
61 | # endif |
62 | is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, |
63 | "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" |
64 | " or 'char8_t'" ); |
65 | string __tmp; |
66 | const char __sentinel = char{}; |
67 | for (; *__f != __sentinel; ++__f) |
68 | __tmp.push_back(*__f); |
69 | using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; |
70 | std::wstring __w; |
71 | __w.reserve(__tmp.size()); |
72 | _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); |
73 | return path(__w); |
74 | } |
75 | # endif /* _LIBCPP_WIN32API */ |
76 | |
77 | template <class _Source, __enable_if_t<__is_pathable<_Source>::value, int> = 0> |
78 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) { |
79 | static_assert( |
80 | # ifndef _LIBCPP_HAS_NO_CHAR8_T |
81 | is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value || |
82 | # endif |
83 | is_same<typename __is_pathable<_Source>::__char_type, char>::value, |
84 | "u8path(Source const&) requires Source have a character type of type " |
85 | "'char' or 'char8_t'" ); |
86 | # if defined(_LIBCPP_WIN32API) |
87 | using _Traits = __is_pathable<_Source>; |
88 | return u8path(std::__unwrap_iter(_Traits::__range_begin(__s)), std::__unwrap_iter(_Traits::__range_end(__s))); |
89 | # else |
90 | return path(__s); |
91 | # endif |
92 | } |
93 | |
94 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP |
95 | |
96 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
97 | |
98 | #endif // _LIBCPP_STD_VER >= 17 |
99 | |
100 | #endif // _LIBCPP___FILESYSTEM_U8PATH_H |
101 | |