path_traits.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. // filesystem path_traits.hpp --------------------------------------------------------//
  2. // Copyright Beman Dawes 2009
  3. // Copyright Andrey Semashev 2022
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See http://www.boost.org/LICENSE_1_0.txt
  6. // Library home page: http://www.boost.org/libs/filesystem
  7. #ifndef BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP
  8. #define BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP
  9. #include <boost/filesystem/config.hpp>
  10. #include <cstddef>
  11. #include <cstring> // for strlen
  12. #include <cwchar> // for mbstate_t, wcslen
  13. #include <locale>
  14. #include <string>
  15. #include <iterator>
  16. #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  17. #include <string_view>
  18. #endif
  19. #include <boost/assert.hpp>
  20. #include <boost/system/error_category.hpp>
  21. #include <boost/iterator/is_iterator.hpp>
  22. #include <boost/type_traits/declval.hpp>
  23. #include <boost/type_traits/remove_cv.hpp>
  24. #include <boost/type_traits/integral_constant.hpp>
  25. #include <boost/type_traits/conjunction.hpp>
  26. #if defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  27. #include <boost/type_traits/disjunction.hpp>
  28. #include <boost/core/enable_if.hpp>
  29. #endif
  30. #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
  31. #include <vector>
  32. #include <list>
  33. #endif
  34. #include <boost/filesystem/detail/header.hpp> // must be the last #include
  35. namespace boost {
  36. template< typename, typename > class basic_string_view;
  37. namespace container {
  38. template< typename, typename, typename > class basic_string;
  39. } // namespace container
  40. namespace filesystem {
  41. BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT;
  42. class directory_entry;
  43. namespace detail {
  44. namespace path_traits {
  45. #if defined(BOOST_WINDOWS_API)
  46. typedef wchar_t path_native_char_type;
  47. #define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE false
  48. #define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE true
  49. #else
  50. typedef char path_native_char_type;
  51. #define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE true
  52. #define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE false
  53. #endif
  54. typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type;
  55. struct unknown_type_tag {};
  56. struct ntcts_type_tag {};
  57. struct char_ptr_tag : ntcts_type_tag {};
  58. struct char_array_tag : ntcts_type_tag {};
  59. struct string_class_tag {};
  60. struct std_string_tag : string_class_tag {};
  61. struct boost_container_string_tag : string_class_tag {};
  62. struct std_string_view_tag : string_class_tag {};
  63. struct boost_string_view_tag : string_class_tag {};
  64. struct range_type_tag {};
  65. struct directory_entry_tag {};
  66. //! The traits define a number of properties of a path source
  67. template< typename T >
  68. struct path_source_traits
  69. {
  70. //! The kind of the path source. Useful for dispatching.
  71. typedef unknown_type_tag tag_type;
  72. //! Character type that the source contains
  73. typedef void char_type;
  74. //! Indicates whether the source is natively supported by \c path::string_type as arguments for constructors/assignment/appending
  75. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  76. };
  77. template< >
  78. struct path_source_traits< char* >
  79. {
  80. typedef char_ptr_tag tag_type;
  81. typedef char char_type;
  82. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  83. };
  84. template< >
  85. struct path_source_traits< const char* >
  86. {
  87. typedef char_ptr_tag tag_type;
  88. typedef char char_type;
  89. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  90. };
  91. template< >
  92. struct path_source_traits< wchar_t* >
  93. {
  94. typedef char_ptr_tag tag_type;
  95. typedef wchar_t char_type;
  96. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  97. };
  98. template< >
  99. struct path_source_traits< const wchar_t* >
  100. {
  101. typedef char_ptr_tag tag_type;
  102. typedef wchar_t char_type;
  103. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  104. };
  105. template< >
  106. struct path_source_traits< char[] >
  107. {
  108. typedef char_array_tag tag_type;
  109. typedef char char_type;
  110. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  111. };
  112. template< >
  113. struct path_source_traits< const char[] >
  114. {
  115. typedef char_array_tag tag_type;
  116. typedef char char_type;
  117. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  118. };
  119. template< >
  120. struct path_source_traits< wchar_t[] >
  121. {
  122. typedef char_array_tag tag_type;
  123. typedef wchar_t char_type;
  124. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  125. };
  126. template< >
  127. struct path_source_traits< const wchar_t[] >
  128. {
  129. typedef char_array_tag tag_type;
  130. typedef wchar_t char_type;
  131. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  132. };
  133. template< std::size_t N >
  134. struct path_source_traits< char[N] >
  135. {
  136. typedef char_array_tag tag_type;
  137. typedef char char_type;
  138. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  139. };
  140. template< std::size_t N >
  141. struct path_source_traits< const char[N] >
  142. {
  143. typedef char_array_tag tag_type;
  144. typedef char char_type;
  145. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  146. };
  147. template< std::size_t N >
  148. struct path_source_traits< wchar_t[N] >
  149. {
  150. typedef char_array_tag tag_type;
  151. typedef wchar_t char_type;
  152. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  153. };
  154. template< std::size_t N >
  155. struct path_source_traits< const wchar_t[N] >
  156. {
  157. typedef char_array_tag tag_type;
  158. typedef wchar_t char_type;
  159. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  160. };
  161. template< >
  162. struct path_source_traits< std::string >
  163. {
  164. typedef std_string_tag tag_type;
  165. typedef char char_type;
  166. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  167. };
  168. template< >
  169. struct path_source_traits< std::wstring >
  170. {
  171. typedef std_string_tag tag_type;
  172. typedef wchar_t char_type;
  173. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  174. };
  175. template< >
  176. struct path_source_traits< boost::container::basic_string< char, std::char_traits< char >, void > >
  177. {
  178. typedef boost_container_string_tag tag_type;
  179. typedef char char_type;
  180. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  181. };
  182. template< >
  183. struct path_source_traits< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > >
  184. {
  185. typedef boost_container_string_tag tag_type;
  186. typedef wchar_t char_type;
  187. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  188. };
  189. #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  190. template< >
  191. struct path_source_traits< std::string_view >
  192. {
  193. typedef std_string_view_tag tag_type;
  194. typedef char char_type;
  195. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE;
  196. };
  197. template< >
  198. struct path_source_traits< std::wstring_view >
  199. {
  200. typedef std_string_view_tag tag_type;
  201. typedef wchar_t char_type;
  202. static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE;
  203. };
  204. #endif // !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  205. template< >
  206. struct path_source_traits< boost::basic_string_view< char, std::char_traits< char > > >
  207. {
  208. typedef boost_string_view_tag tag_type;
  209. typedef char char_type;
  210. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  211. };
  212. template< >
  213. struct path_source_traits< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > >
  214. {
  215. typedef boost_string_view_tag tag_type;
  216. typedef wchar_t char_type;
  217. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  218. };
  219. #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
  220. template< >
  221. struct
  222. BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
  223. path_source_traits< std::vector< char > >
  224. {
  225. // Since C++11 this could be string_class_tag as std::vector gained data() member
  226. typedef range_type_tag tag_type;
  227. typedef char char_type;
  228. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  229. };
  230. template< >
  231. struct
  232. BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
  233. path_source_traits< std::vector< wchar_t > >
  234. {
  235. // Since C++11 this could be string_class_tag as std::vector gained data() member
  236. typedef range_type_tag tag_type;
  237. typedef wchar_t char_type;
  238. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  239. };
  240. template< >
  241. struct
  242. BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
  243. path_source_traits< std::list< char > >
  244. {
  245. typedef range_type_tag tag_type;
  246. typedef char char_type;
  247. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  248. };
  249. template< >
  250. struct
  251. BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
  252. path_source_traits< std::list< wchar_t > >
  253. {
  254. typedef range_type_tag tag_type;
  255. typedef wchar_t char_type;
  256. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  257. };
  258. #endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
  259. template< >
  260. struct path_source_traits< directory_entry >
  261. {
  262. typedef directory_entry_tag tag_type;
  263. typedef path_native_char_type char_type;
  264. static BOOST_CONSTEXPR_OR_CONST bool is_native = false;
  265. };
  266. #undef BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE
  267. #undef BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE
  268. //! The trait tests if the type is a known path Source tag
  269. template< typename Tag >
  270. struct is_known_path_source_tag :
  271. public boost::true_type
  272. {
  273. };
  274. template< >
  275. struct is_known_path_source_tag< unknown_type_tag > :
  276. public boost::false_type
  277. {
  278. };
  279. //! The trait tests if the type is compatible with path Source requirements
  280. template< typename T >
  281. struct is_path_source :
  282. public is_known_path_source_tag< typename path_source_traits< T >::tag_type >::type
  283. {
  284. };
  285. //! The trait indicates whether the type is a path Source that is natively supported by path::string_type as the source for construction/assignment/appending
  286. template< typename T >
  287. struct is_native_path_source :
  288. public boost::integral_constant< bool, path_source_traits< T >::is_native >
  289. {
  290. };
  291. //! The trait indicates whether the type is one of the supported path character types
  292. template< typename T >
  293. struct is_path_char_type :
  294. public boost::false_type
  295. {
  296. };
  297. template< >
  298. struct is_path_char_type< char > :
  299. public boost::true_type
  300. {
  301. };
  302. template< >
  303. struct is_path_char_type< wchar_t > :
  304. public boost::true_type
  305. {
  306. };
  307. template< typename Iterator >
  308. struct is_iterator_to_path_chars :
  309. public is_path_char_type< typename std::iterator_traits< Iterator >::value_type >::type
  310. {
  311. };
  312. //! The trait indicates whether the type is an iterator over a sequence of path characters
  313. template< typename Iterator >
  314. struct is_path_source_iterator :
  315. public boost::conjunction<
  316. boost::iterators::is_iterator< Iterator >,
  317. is_iterator_to_path_chars< Iterator >
  318. >::type
  319. {
  320. };
  321. //! The trait indicates whether the type is a pointer to a sequence of native path characters
  322. template< typename T >
  323. struct is_native_char_ptr :
  324. public boost::false_type
  325. {
  326. };
  327. template< >
  328. struct is_native_char_ptr< path_native_char_type* > :
  329. public boost::true_type
  330. {
  331. };
  332. template< >
  333. struct is_native_char_ptr< const path_native_char_type* > :
  334. public boost::true_type
  335. {
  336. };
  337. //! Converts character encoding using the supplied codecvt facet. If \a cvt is \c NULL then \c path::codecvt() will be used.
  338. BOOST_FILESYSTEM_DECL
  339. void convert(const char* from, const char* from_end, std::wstring& to, const codecvt_type* cvt = NULL);
  340. //! \overload convert
  341. BOOST_FILESYSTEM_DECL
  342. void convert(const wchar_t* from, const wchar_t* from_end, std::string& to, const codecvt_type* cvt = NULL);
  343. // Source dispatch -----------------------------------------------------------------//
  344. template< typename Source, typename Callback >
  345. typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt = NULL);
  346. template< typename Callback >
  347. BOOST_FORCEINLINE typename Callback::result_type dispatch(const char* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
  348. {
  349. return cb(source, source + std::strlen(source), cvt);
  350. }
  351. template< typename Callback >
  352. BOOST_FORCEINLINE typename Callback::result_type dispatch(const wchar_t* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
  353. {
  354. return cb(source, source + std::wcslen(source), cvt);
  355. }
  356. template< typename Source, typename Callback >
  357. BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, string_class_tag)
  358. {
  359. return cb(source.data(), source.data() + source.size(), cvt);
  360. }
  361. template< typename Source, typename Callback >
  362. BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
  363. {
  364. std::basic_string< typename Source::value_type > src(source.begin(), source.end());
  365. return cb(src.data(), src.data() + src.size(), cvt);
  366. }
  367. #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
  368. template< typename Callback >
  369. BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< char > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
  370. {
  371. const char* data = NULL, *data_end = NULL;
  372. if (!source.empty())
  373. {
  374. data = &source[0];
  375. data_end = data + source.size();
  376. }
  377. return cb(data, data_end, cvt);
  378. }
  379. template< typename Callback >
  380. BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< wchar_t > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
  381. {
  382. const wchar_t* data = NULL, *data_end = NULL;
  383. if (!source.empty())
  384. {
  385. data = &source[0];
  386. data_end = data + source.size();
  387. }
  388. return cb(data, data_end, cvt);
  389. }
  390. #endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
  391. // Defined in directory.hpp to avoid circular header dependencies
  392. template< typename Callback >
  393. typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag);
  394. template< typename Source, typename Callback >
  395. BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt)
  396. {
  397. return path_traits::dispatch(source, cb, cvt,
  398. typename path_traits::path_source_traits< typename boost::remove_cv< Source >::type >::tag_type());
  399. }
  400. typedef char yes_type;
  401. struct no_type { char buf[2]; };
  402. #if !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  403. namespace is_convertible_to_path_source_impl {
  404. yes_type check_convertible(const char*);
  405. yes_type check_convertible(const wchar_t*);
  406. yes_type check_convertible(std::string const&);
  407. yes_type check_convertible(std::wstring const&);
  408. yes_type check_convertible(boost::container::basic_string< char, std::char_traits< char >, void > const&);
  409. yes_type check_convertible(boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const&);
  410. #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  411. yes_type check_convertible(std::string_view const&);
  412. yes_type check_convertible(std::wstring_view const&);
  413. #endif
  414. yes_type check_convertible(boost::basic_string_view< char, std::char_traits< char > > const&);
  415. yes_type check_convertible(boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const&);
  416. #if !defined(BOOST_NO_CXX11_NULLPTR)
  417. no_type check_convertible(std::nullptr_t);
  418. #endif
  419. no_type check_convertible(...);
  420. } // namespace is_convertible_to_path_source_impl
  421. //! The type trait indicates whether the type has a conversion path to one of the path source types
  422. template< typename T >
  423. struct is_convertible_to_path_source :
  424. public boost::integral_constant<
  425. bool,
  426. sizeof(is_convertible_to_path_source_impl::check_convertible(boost::declval< T const& >())) == sizeof(yes_type)
  427. >
  428. {
  429. };
  430. #else // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  431. // Note: We use separate checks for convertibility to std::string_view and other types to avoid ambiguity with an implicit range constructor
  432. // of std::string_view in the early C++23 draft (N4892). If a user's type is convertible to e.g. std::string and also satisfies
  433. // ranges::contiguous_range and ranges::sized_range concepts then the conversion is ambiguous: the type is convertible to std::string
  434. // through the conversion operator in the user's class and is also convertible to std::string_view through the implicit conversion
  435. // constructor in std::string_view. The solution is to check convertibility to std::string_view separately first.
  436. namespace is_convertible_to_std_string_view_impl {
  437. yes_type check_convertible(std::string_view const&);
  438. yes_type check_convertible(std::wstring_view const&);
  439. #if !defined(BOOST_NO_CXX11_NULLPTR)
  440. no_type check_convertible(std::nullptr_t);
  441. #endif
  442. no_type check_convertible(...);
  443. } // namespace is_convertible_to_std_string_view_impl
  444. template< typename T >
  445. struct is_convertible_to_std_string_view :
  446. public boost::integral_constant<
  447. bool,
  448. sizeof(is_convertible_to_std_string_view_impl::check_convertible(boost::declval< T const& >())) == sizeof(yes_type)
  449. >
  450. {
  451. };
  452. namespace is_convertible_to_path_source_non_std_string_view_impl {
  453. yes_type check_convertible(const char*);
  454. yes_type check_convertible(const wchar_t*);
  455. yes_type check_convertible(std::string const&);
  456. yes_type check_convertible(std::wstring const&);
  457. yes_type check_convertible(boost::container::basic_string< char, std::char_traits< char >, void > const&);
  458. yes_type check_convertible(boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const&);
  459. yes_type check_convertible(boost::basic_string_view< char, std::char_traits< char > > const&);
  460. yes_type check_convertible(boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const&);
  461. #if !defined(BOOST_NO_CXX11_NULLPTR)
  462. no_type check_convertible(std::nullptr_t);
  463. #endif
  464. no_type check_convertible(...);
  465. } // namespace is_convertible_to_path_source_non_std_string_view_impl
  466. template< typename T >
  467. struct is_convertible_to_path_source_non_std_string_view :
  468. public boost::integral_constant<
  469. bool,
  470. sizeof(is_convertible_to_path_source_non_std_string_view_impl::check_convertible(boost::declval< T const& >())) == sizeof(yes_type)
  471. >
  472. {
  473. };
  474. //! The type trait indicates whether the type has a conversion path to one of the path source types
  475. template< typename T >
  476. struct is_convertible_to_path_source :
  477. public boost::disjunction<
  478. is_convertible_to_std_string_view< T >,
  479. is_convertible_to_path_source_non_std_string_view< T >
  480. >::type
  481. {
  482. };
  483. #endif // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  484. //! The type trait makes \a T dependent on the second template argument. Used to delay type resolution and name binding.
  485. template< typename T, typename >
  486. struct make_dependent
  487. {
  488. typedef T type;
  489. };
  490. template< typename Source, typename Callback >
  491. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const char* source, Callback cb, const codecvt_type* cvt)
  492. {
  493. typedef typename path_traits::make_dependent< const char*, Source >::type source_t;
  494. return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
  495. }
  496. template< typename Source, typename Callback >
  497. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const wchar_t* source, Callback cb, const codecvt_type* cvt)
  498. {
  499. typedef typename path_traits::make_dependent< const wchar_t*, Source >::type source_t;
  500. return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
  501. }
  502. template< typename Source, typename Callback >
  503. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string const& source, Callback cb, const codecvt_type* cvt)
  504. {
  505. typedef typename path_traits::make_dependent< std::string, Source >::type source_t;
  506. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  507. }
  508. template< typename Source, typename Callback >
  509. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring const& source, Callback cb, const codecvt_type* cvt)
  510. {
  511. typedef typename path_traits::make_dependent< std::wstring, Source >::type source_t;
  512. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  513. }
  514. template< typename Source, typename Callback >
  515. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
  516. (
  517. boost::container::basic_string< char, std::char_traits< char >, void > const& source,
  518. Callback cb,
  519. const codecvt_type* cvt
  520. )
  521. {
  522. typedef typename path_traits::make_dependent< boost::container::basic_string< char, std::char_traits< char >, void >, Source >::type source_t;
  523. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  524. }
  525. template< typename Source, typename Callback >
  526. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
  527. (
  528. boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const& source,
  529. Callback cb,
  530. const codecvt_type* cvt
  531. )
  532. {
  533. typedef typename path_traits::make_dependent< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void >, Source >::type source_t;
  534. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  535. }
  536. template< typename Source, typename Callback >
  537. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
  538. (
  539. boost::basic_string_view< char, std::char_traits< char > > const& source,
  540. Callback cb,
  541. const codecvt_type* cvt
  542. )
  543. {
  544. typedef typename path_traits::make_dependent< boost::basic_string_view< char, std::char_traits< char > >, Source >::type source_t;
  545. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  546. }
  547. template< typename Source, typename Callback >
  548. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
  549. (
  550. boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const& source,
  551. Callback cb,
  552. const codecvt_type* cvt
  553. )
  554. {
  555. typedef typename path_traits::make_dependent< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > >, Source >::type source_t;
  556. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  557. }
  558. #if !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  559. #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  560. template< typename Source, typename Callback >
  561. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
  562. {
  563. typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
  564. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  565. }
  566. template< typename Source, typename Callback >
  567. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
  568. {
  569. typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
  570. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  571. }
  572. #endif // !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  573. template< typename Source, typename Callback >
  574. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
  575. {
  576. typedef typename boost::remove_cv< Source >::type source_t;
  577. return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
  578. }
  579. #else // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  580. template< typename Source, typename Callback >
  581. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
  582. {
  583. typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
  584. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  585. }
  586. template< typename Source, typename Callback >
  587. BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
  588. {
  589. typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
  590. return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
  591. }
  592. template< typename Source, typename Callback >
  593. BOOST_FORCEINLINE typename boost::disable_if_c<
  594. is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value,
  595. typename Callback::result_type
  596. >::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
  597. {
  598. typedef typename boost::remove_cv< Source >::type source_t;
  599. return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
  600. }
  601. template< typename Source, typename Callback >
  602. BOOST_FORCEINLINE typename boost::enable_if_c<
  603. is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value,
  604. typename Callback::result_type
  605. >::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
  606. {
  607. typedef typename boost::remove_cv< Source >::type source_t;
  608. return path_traits::dispatch_convertible_sv_impl< source_t >(source, cb, cvt);
  609. }
  610. #endif // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
  611. } // namespace path_traits
  612. } // namespace detail
  613. } // namespace filesystem
  614. } // namespace boost
  615. #include <boost/filesystem/detail/footer.hpp>
  616. #endif // BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP