xref: /freebsd-src/contrib/llvm-project/libcxx/include/__filesystem/u8path.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10eae32dcSDimitry Andric // -*- C++ -*-
20eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
30eae32dcSDimitry Andric //
40eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70eae32dcSDimitry Andric //
80eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
90eae32dcSDimitry Andric 
100eae32dcSDimitry Andric #ifndef _LIBCPP___FILESYSTEM_U8PATH_H
110eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_U8PATH_H
120eae32dcSDimitry Andric 
1381ad6265SDimitry Andric #include <__algorithm/unwrap_iter.h>
140eae32dcSDimitry Andric #include <__config>
150eae32dcSDimitry Andric #include <__filesystem/path.h>
1681ad6265SDimitry Andric #include <string>
170eae32dcSDimitry Andric 
1881ad6265SDimitry Andric // Only required on Windows for __widen_from_utf8, and included conservatively
1981ad6265SDimitry Andric // because it requires support for localization.
2081ad6265SDimitry Andric #if defined(_LIBCPP_WIN32API)
2181ad6265SDimitry Andric #  include <locale>
2281ad6265SDimitry Andric #endif
2381ad6265SDimitry Andric 
2481ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2581ad6265SDimitry Andric #  pragma GCC system_header
2681ad6265SDimitry Andric #endif
2781ad6265SDimitry Andric 
285f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17
290eae32dcSDimitry Andric 
300eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
310eae32dcSDimitry Andric 
3206c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
330eae32dcSDimitry Andric 
345f757f3fSDimitry Andric template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
35*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) {
360eae32dcSDimitry Andric   static_assert(
370eae32dcSDimitry Andric #  ifndef _LIBCPP_HAS_NO_CHAR8_T
380eae32dcSDimitry Andric       is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
390eae32dcSDimitry Andric #  endif
400eae32dcSDimitry Andric           is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
410eae32dcSDimitry Andric       "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
420eae32dcSDimitry Andric       " or 'char8_t'");
430eae32dcSDimitry Andric #  if defined(_LIBCPP_WIN32API)
440eae32dcSDimitry Andric   string __tmp(__f, __l);
450eae32dcSDimitry Andric   using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
465f757f3fSDimitry Andric   std::wstring __w;
470eae32dcSDimitry Andric   __w.reserve(__tmp.size());
480eae32dcSDimitry Andric   _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
490eae32dcSDimitry Andric   return path(__w);
500eae32dcSDimitry Andric #  else
510eae32dcSDimitry Andric   return path(__f, __l);
520eae32dcSDimitry Andric #  endif /* !_LIBCPP_WIN32API */
530eae32dcSDimitry Andric }
540eae32dcSDimitry Andric 
550eae32dcSDimitry Andric #  if defined(_LIBCPP_WIN32API)
565f757f3fSDimitry Andric template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
57*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
580eae32dcSDimitry Andric   static_assert(
590eae32dcSDimitry Andric #    ifndef _LIBCPP_HAS_NO_CHAR8_T
600eae32dcSDimitry Andric       is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
610eae32dcSDimitry Andric #    endif
620eae32dcSDimitry Andric           is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
630eae32dcSDimitry Andric       "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
640eae32dcSDimitry Andric       " or 'char8_t'");
650eae32dcSDimitry Andric   string __tmp;
660eae32dcSDimitry Andric   const char __sentinel = char{};
670eae32dcSDimitry Andric   for (; *__f != __sentinel; ++__f)
680eae32dcSDimitry Andric     __tmp.push_back(*__f);
690eae32dcSDimitry Andric   using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
705f757f3fSDimitry Andric   std::wstring __w;
710eae32dcSDimitry Andric   __w.reserve(__tmp.size());
720eae32dcSDimitry Andric   _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
730eae32dcSDimitry Andric   return path(__w);
740eae32dcSDimitry Andric }
750eae32dcSDimitry Andric #  endif /* _LIBCPP_WIN32API */
760eae32dcSDimitry Andric 
775f757f3fSDimitry Andric template <class _Source, __enable_if_t<__is_pathable<_Source>::value, int> = 0>
78*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) {
790eae32dcSDimitry Andric   static_assert(
800eae32dcSDimitry Andric #  ifndef _LIBCPP_HAS_NO_CHAR8_T
810eae32dcSDimitry Andric       is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
820eae32dcSDimitry Andric #  endif
830eae32dcSDimitry Andric           is_same<typename __is_pathable<_Source>::__char_type, char>::value,
840eae32dcSDimitry Andric       "u8path(Source const&) requires Source have a character type of type "
850eae32dcSDimitry Andric       "'char' or 'char8_t'");
860eae32dcSDimitry Andric #  if defined(_LIBCPP_WIN32API)
870eae32dcSDimitry Andric   using _Traits = __is_pathable<_Source>;
885f757f3fSDimitry Andric   return u8path(std::__unwrap_iter(_Traits::__range_begin(__s)), std::__unwrap_iter(_Traits::__range_end(__s)));
890eae32dcSDimitry Andric #  else
900eae32dcSDimitry Andric   return path(__s);
910eae32dcSDimitry Andric #  endif
920eae32dcSDimitry Andric }
930eae32dcSDimitry Andric 
9406c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
950eae32dcSDimitry Andric 
960eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
970eae32dcSDimitry Andric 
985f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17
990eae32dcSDimitry Andric 
1000eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_U8PATH_H
101