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 <__availability>
15 #include <__config>
16 #include <__filesystem/path.h>
17 #include <string>
18 
19 // Only required on Windows for __widen_from_utf8, and included conservatively
20 // because it requires support for localization.
21 #if defined(_LIBCPP_WIN32API)
22 # include <locale>
23 #endif
24 
25 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26 #  pragma GCC system_header
27 #endif
28 
29 #ifndef _LIBCPP_CXX03_LANG
30 
31 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
32 
33 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
34 
35 template <class _InputIt>
36 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
37     typename enable_if<__is_pathable<_InputIt>::value, path>::type
38     u8path(_InputIt __f, _InputIt __l) {
39   static_assert(
40 #ifndef _LIBCPP_HAS_NO_CHAR8_T
41       is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
42 #endif
43       is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
44       "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
45       " or 'char8_t'");
46 #if defined(_LIBCPP_WIN32API)
47   string __tmp(__f, __l);
48   using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
49   _VSTD::wstring __w;
50   __w.reserve(__tmp.size());
51   _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
52   return path(__w);
53 #else
54   return path(__f, __l);
55 #endif /* !_LIBCPP_WIN32API */
56 }
57 
58 #if defined(_LIBCPP_WIN32API)
59 template <class _InputIt>
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
61     typename enable_if<__is_pathable<_InputIt>::value, path>::type
62     u8path(_InputIt __f, _NullSentinel) {
63   static_assert(
64 #ifndef _LIBCPP_HAS_NO_CHAR8_T
65       is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
66 #endif
67       is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
68       "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
69       " or 'char8_t'");
70   string __tmp;
71   const char __sentinel = char{};
72   for (; *__f != __sentinel; ++__f)
73     __tmp.push_back(*__f);
74   using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
75   _VSTD::wstring __w;
76   __w.reserve(__tmp.size());
77   _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
78   return path(__w);
79 }
80 #endif /* _LIBCPP_WIN32API */
81 
82 template <class _Source>
83 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
84     typename enable_if<__is_pathable<_Source>::value, path>::type
85     u8path(const _Source& __s) {
86   static_assert(
87 #ifndef _LIBCPP_HAS_NO_CHAR8_T
88       is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
89 #endif
90       is_same<typename __is_pathable<_Source>::__char_type, char>::value,
91       "u8path(Source const&) requires Source have a character type of type "
92       "'char' or 'char8_t'");
93 #if defined(_LIBCPP_WIN32API)
94   using _Traits = __is_pathable<_Source>;
95   return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s)));
96 #else
97   return path(__s);
98 #endif
99 }
100 
101 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
102 
103 _LIBCPP_END_NAMESPACE_FILESYSTEM
104 
105 #endif // _LIBCPP_CXX03_LANG
106 
107 #endif // _LIBCPP___FILESYSTEM_U8PATH_H
108