path_traits.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // filesystem path_traits.hpp --------------------------------------------------------//
  2. // Copyright Beman Dawes 2009
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See http://www.boost.org/LICENSE_1_0.txt
  5. // Library home page: http://www.boost.org/libs/filesystem
  6. #ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP
  7. #define BOOST_FILESYSTEM_PATH_TRAITS_HPP
  8. #include <boost/filesystem/config.hpp>
  9. #include <boost/system/error_category.hpp>
  10. #include <boost/type_traits/is_array.hpp>
  11. #include <boost/type_traits/decay.hpp>
  12. #include <boost/core/enable_if.hpp>
  13. #include <cstddef>
  14. #include <cwchar> // for mbstate_t
  15. #include <string>
  16. #include <vector>
  17. #include <list>
  18. #include <iterator>
  19. #include <locale>
  20. #include <boost/assert.hpp>
  21. #include <boost/filesystem/detail/header.hpp> // must be the last #include
  22. namespace boost {
  23. namespace filesystem {
  24. BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT;
  25. // uses std::codecvt_base::result used for error codes:
  26. //
  27. // ok: Conversion successful.
  28. // partial: Not all source characters converted; one or more additional source
  29. // characters are needed to produce the final target character, or the
  30. // size of the target intermediate buffer was too small to hold the result.
  31. // error: A character in the source could not be converted to the target encoding.
  32. // noconv: The source and target characters have the same type and encoding, so no
  33. // conversion was necessary.
  34. class directory_entry;
  35. namespace path_traits {
  36. typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type;
  37. // is_pathable type trait; allows disabling over-agressive class path member templates
  38. template< class T >
  39. struct is_pathable
  40. {
  41. static const bool value = false;
  42. };
  43. template<>
  44. struct is_pathable< char* >
  45. {
  46. static const bool value = true;
  47. };
  48. template<>
  49. struct is_pathable< const char* >
  50. {
  51. static const bool value = true;
  52. };
  53. template<>
  54. struct is_pathable< wchar_t* >
  55. {
  56. static const bool value = true;
  57. };
  58. template<>
  59. struct is_pathable< const wchar_t* >
  60. {
  61. static const bool value = true;
  62. };
  63. template<>
  64. struct is_pathable< std::string >
  65. {
  66. static const bool value = true;
  67. };
  68. template<>
  69. struct is_pathable< std::wstring >
  70. {
  71. static const bool value = true;
  72. };
  73. template<>
  74. struct is_pathable< std::vector< char > >
  75. {
  76. static const bool value = true;
  77. };
  78. template<>
  79. struct is_pathable< std::vector< wchar_t > >
  80. {
  81. static const bool value = true;
  82. };
  83. template<>
  84. struct is_pathable< std::list< char > >
  85. {
  86. static const bool value = true;
  87. };
  88. template<>
  89. struct is_pathable< std::list< wchar_t > >
  90. {
  91. static const bool value = true;
  92. };
  93. template<>
  94. struct is_pathable< directory_entry >
  95. {
  96. static const bool value = true;
  97. };
  98. // Pathable empty
  99. template< class Container >
  100. inline
  101. // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
  102. // conforming compilers. Replace by plain "bool" at some future date (2012?)
  103. typename boost::disable_if< boost::is_array< Container >, bool >::type
  104. empty(Container const& c)
  105. {
  106. return c.begin() == c.end();
  107. }
  108. template< class T >
  109. inline bool empty(T* const& c_str)
  110. {
  111. BOOST_ASSERT(c_str);
  112. return !*c_str;
  113. }
  114. template< typename T, std::size_t N >
  115. inline bool empty(T (&x)[N])
  116. {
  117. return !x[0];
  118. }
  119. // value types differ ---------------------------------------------------------------//
  120. //
  121. // A from_end argument of 0 is less efficient than a known end, so use only if needed
  122. // with codecvt
  123. BOOST_FILESYSTEM_DECL
  124. void convert(const char* from,
  125. const char* from_end, // 0 for null terminated MBCS
  126. std::wstring& to, codecvt_type const& cvt);
  127. BOOST_FILESYSTEM_DECL
  128. void convert(const wchar_t* from,
  129. const wchar_t* from_end, // 0 for null terminated MBCS
  130. std::string& to, codecvt_type const& cvt);
  131. inline void convert(const char* from, std::wstring& to, codecvt_type const& cvt)
  132. {
  133. BOOST_ASSERT(from);
  134. convert(from, 0, to, cvt);
  135. }
  136. inline void convert(const wchar_t* from, std::string& to, codecvt_type const& cvt)
  137. {
  138. BOOST_ASSERT(from);
  139. convert(from, 0, to, cvt);
  140. }
  141. // without codecvt
  142. inline void convert(const char* from,
  143. const char* from_end, // 0 for null terminated MBCS
  144. std::wstring& to);
  145. inline void convert(const wchar_t* from,
  146. const wchar_t* from_end, // 0 for null terminated MBCS
  147. std::string& to);
  148. inline void convert(const char* from, std::wstring& to);
  149. inline void convert(const wchar_t* from, std::string& to);
  150. // value types same -----------------------------------------------------------------//
  151. // char with codecvt
  152. inline void convert(const char* from, const char* from_end, std::string& to, codecvt_type const&)
  153. {
  154. BOOST_ASSERT(from);
  155. BOOST_ASSERT(from_end);
  156. to.append(from, from_end);
  157. }
  158. inline void convert(const char* from, std::string& to, codecvt_type const&)
  159. {
  160. BOOST_ASSERT(from);
  161. to += from;
  162. }
  163. // wchar_t with codecvt
  164. inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to, codecvt_type const&)
  165. {
  166. BOOST_ASSERT(from);
  167. BOOST_ASSERT(from_end);
  168. to.append(from, from_end);
  169. }
  170. inline void convert(const wchar_t* from, std::wstring& to, codecvt_type const&)
  171. {
  172. BOOST_ASSERT(from);
  173. to += from;
  174. }
  175. // char without codecvt
  176. inline void convert(const char* from, const char* from_end, std::string& to)
  177. {
  178. BOOST_ASSERT(from);
  179. BOOST_ASSERT(from_end);
  180. to.append(from, from_end);
  181. }
  182. inline void convert(const char* from, std::string& to)
  183. {
  184. BOOST_ASSERT(from);
  185. to += from;
  186. }
  187. // wchar_t without codecvt
  188. inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to)
  189. {
  190. BOOST_ASSERT(from);
  191. BOOST_ASSERT(from_end);
  192. to.append(from, from_end);
  193. }
  194. inline void convert(const wchar_t* from, std::wstring& to)
  195. {
  196. BOOST_ASSERT(from);
  197. to += from;
  198. }
  199. // Source dispatch -----------------------------------------------------------------//
  200. // contiguous containers with codecvt
  201. template< class U >
  202. inline void dispatch(std::string const& c, U& to, codecvt_type const& cvt)
  203. {
  204. if (!c.empty())
  205. convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
  206. }
  207. template< class U >
  208. inline void dispatch(std::wstring const& c, U& to, codecvt_type const& cvt)
  209. {
  210. if (!c.empty())
  211. convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
  212. }
  213. template< class U >
  214. inline void dispatch(std::vector< char > const& c, U& to, codecvt_type const& cvt)
  215. {
  216. if (!c.empty())
  217. convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
  218. }
  219. template< class U >
  220. inline void dispatch(std::vector< wchar_t > const& c, U& to, codecvt_type const& cvt)
  221. {
  222. if (!c.empty())
  223. convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
  224. }
  225. // contiguous containers without codecvt
  226. template< class U >
  227. inline void dispatch(std::string const& c, U& to)
  228. {
  229. if (!c.empty())
  230. convert(&*c.begin(), &*c.begin() + c.size(), to);
  231. }
  232. template< class U >
  233. inline void dispatch(std::wstring const& c, U& to)
  234. {
  235. if (!c.empty())
  236. convert(&*c.begin(), &*c.begin() + c.size(), to);
  237. }
  238. template< class U >
  239. inline void dispatch(std::vector< char > const& c, U& to)
  240. {
  241. if (!c.empty())
  242. convert(&*c.begin(), &*c.begin() + c.size(), to);
  243. }
  244. template< class U >
  245. inline void dispatch(std::vector< wchar_t > const& c, U& to)
  246. {
  247. if (!c.empty())
  248. convert(&*c.begin(), &*c.begin() + c.size(), to);
  249. }
  250. // non-contiguous containers with codecvt
  251. template< class Container, class U >
  252. inline
  253. // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
  254. // conforming compilers. Replace by plain "void" at some future date (2012?)
  255. typename boost::disable_if< boost::is_array< Container >, void >::type
  256. dispatch(Container const& c, U& to, codecvt_type const& cvt)
  257. {
  258. if (!c.empty())
  259. {
  260. std::basic_string< typename Container::value_type > s(c.begin(), c.end());
  261. convert(s.c_str(), s.c_str() + s.size(), to, cvt);
  262. }
  263. }
  264. // c_str
  265. template< class T, class U >
  266. inline void dispatch(T* const& c_str, U& to, codecvt_type const& cvt)
  267. {
  268. // std::cout << "dispatch() const T *\n";
  269. BOOST_ASSERT(c_str);
  270. convert(c_str, to, cvt);
  271. }
  272. // Note: there is no dispatch on C-style arrays because the array may
  273. // contain a string smaller than the array size.
  274. BOOST_FILESYSTEM_DECL
  275. void dispatch(directory_entry const& de,
  276. #ifdef BOOST_WINDOWS_API
  277. std::wstring& to,
  278. #else
  279. std::string& to,
  280. #endif
  281. codecvt_type const&);
  282. // non-contiguous containers without codecvt
  283. template< class Container, class U >
  284. inline
  285. // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
  286. // conforming compilers. Replace by plain "void" at some future date (2012?)
  287. typename boost::disable_if< boost::is_array< Container >, void >::type
  288. dispatch(Container const& c, U& to)
  289. {
  290. if (!c.empty())
  291. {
  292. std::basic_string< typename Container::value_type > seq(c.begin(), c.end());
  293. convert(seq.c_str(), seq.c_str() + seq.size(), to);
  294. }
  295. }
  296. // c_str
  297. template< class T, class U >
  298. inline void dispatch(T* const& c_str, U& to)
  299. {
  300. // std::cout << "dispatch() const T *\n";
  301. BOOST_ASSERT(c_str);
  302. convert(c_str, to);
  303. }
  304. // Note: there is no dispatch on C-style arrays because the array may
  305. // contain a string smaller than the array size.
  306. BOOST_FILESYSTEM_DECL
  307. void dispatch(directory_entry const& de,
  308. #ifdef BOOST_WINDOWS_API
  309. std::wstring& to
  310. #else
  311. std::string& to
  312. #endif
  313. );
  314. } // namespace path_traits
  315. } // namespace filesystem
  316. } // namespace boost
  317. #include <boost/filesystem/detail/footer.hpp>
  318. #endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP