filesystem 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052
  1. // -*- C++ -*-
  2. //===--------------------------- filesystem -------------------------------===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is dual licensed under the MIT and the University of Illinois Open
  7. // Source Licenses. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #ifndef _LIBCPP_EXPERIMENTAL_FILESYSTEM
  11. #define _LIBCPP_EXPERIMENTAL_FILESYSTEM
  12. /*
  13. filesystem synopsis
  14. namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
  15. class path;
  16. void swap(path& lhs, path& rhs) _NOEXCEPT;
  17. size_t hash_value(const path& p) _NOEXCEPT;
  18. bool operator==(const path& lhs, const path& rhs) _NOEXCEPT;
  19. bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT;
  20. bool operator< (const path& lhs, const path& rhs) _NOEXCEPT;
  21. bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT;
  22. bool operator> (const path& lhs, const path& rhs) _NOEXCEPT;
  23. bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT;
  24. path operator/ (const path& lhs, const path& rhs);
  25. template <class charT, class traits>
  26. basic_ostream<charT, traits>&
  27. operator<<(basic_ostream<charT, traits>& os, const path& p);
  28. template <class charT, class traits>
  29. basic_istream<charT, traits>&
  30. operator>>(basic_istream<charT, traits>& is, path& p);
  31. template <class Source>
  32. path u8path(const Source& source);
  33. template <class InputIterator>
  34. path u8path(InputIterator first, InputIterator last);
  35. class filesystem_error;
  36. class directory_entry;
  37. class directory_iterator;
  38. // enable directory_iterator range-based for statements
  39. directory_iterator begin(directory_iterator iter) noexcept;
  40. directory_iterator end(const directory_iterator&) noexcept;
  41. class recursive_directory_iterator;
  42. // enable recursive_directory_iterator range-based for statements
  43. recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
  44. recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
  45. class file_status;
  46. struct space_info
  47. {
  48. uintmax_t capacity;
  49. uintmax_t free;
  50. uintmax_t available;
  51. };
  52. enum class file_type;
  53. enum class perms;
  54. enum class copy_options;
  55. enum class directory_options;
  56. typedef chrono::time_point<trivial-clock> file_time_type;
  57. // operational functions
  58. path absolute(const path& p, const path& base=current_path());
  59. path canonical(const path& p, const path& base = current_path());
  60. path canonical(const path& p, error_code& ec);
  61. path canonical(const path& p, const path& base, error_code& ec);
  62. void copy(const path& from, const path& to);
  63. void copy(const path& from, const path& to, error_code& ec) _NOEXCEPT;
  64. void copy(const path& from, const path& to, copy_options options);
  65. void copy(const path& from, const path& to, copy_options options,
  66. error_code& ec) _NOEXCEPT;
  67. bool copy_file(const path& from, const path& to);
  68. bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT;
  69. bool copy_file(const path& from, const path& to, copy_options option);
  70. bool copy_file(const path& from, const path& to, copy_options option,
  71. error_code& ec) _NOEXCEPT;
  72. void copy_symlink(const path& existing_symlink, const path& new_symlink);
  73. void copy_symlink(const path& existing_symlink, const path& new_symlink,
  74. error_code& ec) _NOEXCEPT;
  75. bool create_directories(const path& p);
  76. bool create_directories(const path& p, error_code& ec) _NOEXCEPT;
  77. bool create_directory(const path& p);
  78. bool create_directory(const path& p, error_code& ec) _NOEXCEPT;
  79. bool create_directory(const path& p, const path& attributes);
  80. bool create_directory(const path& p, const path& attributes,
  81. error_code& ec) _NOEXCEPT;
  82. void create_directory_symlink(const path& to, const path& new_symlink);
  83. void create_directory_symlink(const path& to, const path& new_symlink,
  84. error_code& ec) _NOEXCEPT;
  85. void create_hard_link(const path& to, const path& new_hard_link);
  86. void create_hard_link(const path& to, const path& new_hard_link,
  87. error_code& ec) _NOEXCEPT;
  88. void create_symlink(const path& to, const path& new_symlink);
  89. void create_symlink(const path& to, const path& new_symlink,
  90. error_code& ec) _NOEXCEPT;
  91. path current_path();
  92. path current_path(error_code& ec);
  93. void current_path(const path& p);
  94. void current_path(const path& p, error_code& ec) _NOEXCEPT;
  95. bool exists(file_status s) _NOEXCEPT;
  96. bool exists(const path& p);
  97. bool exists(const path& p, error_code& ec) _NOEXCEPT;
  98. bool equivalent(const path& p1, const path& p2);
  99. bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT;
  100. uintmax_t file_size(const path& p);
  101. uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT;
  102. uintmax_t hard_link_count(const path& p);
  103. uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT;
  104. bool is_block_file(file_status s) _NOEXCEPT;
  105. bool is_block_file(const path& p);
  106. bool is_block_file(const path& p, error_code& ec) _NOEXCEPT;
  107. bool is_character_file(file_status s) _NOEXCEPT;
  108. bool is_character_file(const path& p);
  109. bool is_character_file(const path& p, error_code& ec) _NOEXCEPT;
  110. bool is_directory(file_status s) _NOEXCEPT;
  111. bool is_directory(const path& p);
  112. bool is_directory(const path& p, error_code& ec) _NOEXCEPT;
  113. bool is_empty(const path& p);
  114. bool is_empty(const path& p, error_code& ec) _NOEXCEPT;
  115. bool is_fifo(file_status s) _NOEXCEPT;
  116. bool is_fifo(const path& p);
  117. bool is_fifo(const path& p, error_code& ec) _NOEXCEPT;
  118. bool is_other(file_status s) _NOEXCEPT;
  119. bool is_other(const path& p);
  120. bool is_other(const path& p, error_code& ec) _NOEXCEPT;
  121. bool is_regular_file(file_status s) _NOEXCEPT;
  122. bool is_regular_file(const path& p);
  123. bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT;
  124. bool is_socket(file_status s) _NOEXCEPT;
  125. bool is_socket(const path& p);
  126. bool is_socket(const path& p, error_code& ec) _NOEXCEPT;
  127. bool is_symlink(file_status s) _NOEXCEPT;
  128. bool is_symlink(const path& p);
  129. bool is_symlink(const path& p, error_code& ec) _NOEXCEPT;
  130. file_time_type last_write_time(const path& p);
  131. file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT;
  132. void last_write_time(const path& p, file_time_type new_time);
  133. void last_write_time(const path& p, file_time_type new_time,
  134. error_code& ec) _NOEXCEPT;
  135. void permissions(const path& p, perms prms);
  136. void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT;
  137. path read_symlink(const path& p);
  138. path read_symlink(const path& p, error_code& ec);
  139. bool remove(const path& p);
  140. bool remove(const path& p, error_code& ec) _NOEXCEPT;
  141. uintmax_t remove_all(const path& p);
  142. uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT;
  143. void rename(const path& from, const path& to);
  144. void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
  145. void resize_file(const path& p, uintmax_t size);
  146. void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT;
  147. space_info space(const path& p);
  148. space_info space(const path& p, error_code& ec) _NOEXCEPT;
  149. file_status status(const path& p);
  150. file_status status(const path& p, error_code& ec) _NOEXCEPT;
  151. bool status_known(file_status s) _NOEXCEPT;
  152. file_status symlink_status(const path& p);
  153. file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
  154. path system_complete(const path& p);
  155. path system_complete(const path& p, error_code& ec);
  156. path temp_directory_path();
  157. path temp_directory_path(error_code& ec);
  158. } } } } // namespaces std::experimental::filesystem::v1
  159. */
  160. #include <experimental/__config>
  161. #include <cstddef>
  162. #include <chrono>
  163. #include <iterator>
  164. #include <iosfwd>
  165. #include <locale>
  166. #include <memory>
  167. #include <stack>
  168. #include <string>
  169. #include <system_error>
  170. #include <utility>
  171. #include <iomanip> // for quoted
  172. #include <experimental/string_view>
  173. #include <__debug>
  174. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  175. #pragma GCC system_header
  176. #endif
  177. #define __cpp_lib_experimental_filesystem 201406
  178. _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
  179. typedef chrono::time_point<std::chrono::system_clock> file_time_type;
  180. struct _LIBCPP_TYPE_VIS space_info
  181. {
  182. uintmax_t capacity;
  183. uintmax_t free;
  184. uintmax_t available;
  185. };
  186. enum class _LIBCPP_TYPE_VIS file_type : signed char
  187. {
  188. none = 0,
  189. not_found = -1,
  190. regular = 1,
  191. directory = 2,
  192. symlink = 3,
  193. block = 4,
  194. character = 5,
  195. fifo = 6,
  196. socket = 7,
  197. unknown = 8
  198. };
  199. enum class _LIBCPP_TYPE_VIS perms : unsigned
  200. {
  201. none = 0,
  202. owner_read = 0400,
  203. owner_write = 0200,
  204. owner_exec = 0100,
  205. owner_all = 0700,
  206. group_read = 040,
  207. group_write = 020,
  208. group_exec = 010,
  209. group_all = 070,
  210. others_read = 04,
  211. others_write = 02,
  212. others_exec = 01,
  213. others_all = 07,
  214. all = 0777,
  215. set_uid = 04000,
  216. set_gid = 02000,
  217. sticky_bit = 01000,
  218. mask = 07777,
  219. unknown = 0xFFFF,
  220. add_perms = 0x10000,
  221. remove_perms = 0x20000,
  222. symlink_nofollow = 0x40000
  223. };
  224. _LIBCPP_INLINE_VISIBILITY
  225. inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
  226. { return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
  227. _LIBCPP_INLINE_VISIBILITY
  228. inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
  229. { return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
  230. _LIBCPP_INLINE_VISIBILITY
  231. inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
  232. { return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
  233. _LIBCPP_INLINE_VISIBILITY
  234. inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
  235. { return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
  236. _LIBCPP_INLINE_VISIBILITY
  237. inline perms& operator&=(perms& _LHS, perms _RHS)
  238. { return _LHS = _LHS & _RHS; }
  239. _LIBCPP_INLINE_VISIBILITY
  240. inline perms& operator|=(perms& _LHS, perms _RHS)
  241. { return _LHS = _LHS | _RHS; }
  242. _LIBCPP_INLINE_VISIBILITY
  243. inline perms& operator^=(perms& _LHS, perms _RHS)
  244. { return _LHS = _LHS ^ _RHS; }
  245. enum class _LIBCPP_TYPE_VIS copy_options : unsigned short
  246. {
  247. none = 0,
  248. skip_existing = 1,
  249. overwrite_existing = 2,
  250. update_existing = 4,
  251. recursive = 8,
  252. copy_symlinks = 16,
  253. skip_symlinks = 32,
  254. directories_only = 64,
  255. create_symlinks = 128,
  256. create_hard_links = 256,
  257. __in_recursive_copy = 512,
  258. };
  259. _LIBCPP_INLINE_VISIBILITY
  260. inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
  261. { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
  262. _LIBCPP_INLINE_VISIBILITY
  263. inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
  264. { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
  265. _LIBCPP_INLINE_VISIBILITY
  266. inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
  267. { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
  268. _LIBCPP_INLINE_VISIBILITY
  269. inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
  270. { return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
  271. _LIBCPP_INLINE_VISIBILITY
  272. inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
  273. { return _LHS = _LHS & _RHS; }
  274. _LIBCPP_INLINE_VISIBILITY
  275. inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
  276. { return _LHS = _LHS | _RHS; }
  277. _LIBCPP_INLINE_VISIBILITY
  278. inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
  279. { return _LHS = _LHS ^ _RHS; }
  280. enum class directory_options : unsigned char
  281. {
  282. none = 0,
  283. follow_directory_symlink = 1,
  284. skip_permission_denied = 2
  285. };
  286. _LIBCPP_INLINE_VISIBILITY
  287. inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
  288. { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
  289. _LIBCPP_INLINE_VISIBILITY
  290. inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
  291. { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
  292. _LIBCPP_INLINE_VISIBILITY
  293. inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
  294. { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
  295. _LIBCPP_INLINE_VISIBILITY
  296. inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
  297. { return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
  298. _LIBCPP_INLINE_VISIBILITY
  299. inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
  300. { return _LHS = _LHS & _RHS; }
  301. _LIBCPP_INLINE_VISIBILITY
  302. inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
  303. { return _LHS = _LHS | _RHS; }
  304. _LIBCPP_INLINE_VISIBILITY
  305. inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
  306. { return _LHS = _LHS ^ _RHS; }
  307. class _LIBCPP_TYPE_VIS file_status
  308. {
  309. public:
  310. // constructors
  311. _LIBCPP_INLINE_VISIBILITY
  312. explicit file_status(file_type __ft = file_type::none,
  313. perms __prms = perms::unknown) _NOEXCEPT
  314. : __ft_(__ft), __prms_(__prms)
  315. {}
  316. file_status(const file_status&) _NOEXCEPT = default;
  317. file_status(file_status&&) _NOEXCEPT = default;
  318. _LIBCPP_INLINE_VISIBILITY
  319. ~file_status() {}
  320. file_status& operator=(const file_status&) _NOEXCEPT = default;
  321. file_status& operator=(file_status&&) _NOEXCEPT = default;
  322. // observers
  323. _LIBCPP_ALWAYS_INLINE
  324. file_type type() const _NOEXCEPT {
  325. return __ft_;
  326. }
  327. _LIBCPP_ALWAYS_INLINE
  328. perms permissions() const _NOEXCEPT {
  329. return __prms_;
  330. }
  331. // modifiers
  332. _LIBCPP_ALWAYS_INLINE
  333. void type(file_type __ft) _NOEXCEPT {
  334. __ft_ = __ft;
  335. }
  336. _LIBCPP_ALWAYS_INLINE
  337. void permissions(perms __p) _NOEXCEPT {
  338. __prms_ = __p;
  339. }
  340. private:
  341. file_type __ft_;
  342. perms __prms_;
  343. };
  344. class _LIBCPP_TYPE_VIS directory_entry;
  345. template <class _Tp> struct __can_convert_char {
  346. static const bool value = false;
  347. };
  348. template <> struct __can_convert_char<char> {
  349. static const bool value = true;
  350. using __char_type = char;
  351. };
  352. template <> struct __can_convert_char<wchar_t> {
  353. static const bool value = true;
  354. using __char_type = wchar_t;
  355. };
  356. template <> struct __can_convert_char<char16_t> {
  357. static const bool value = true;
  358. using __char_type = char16_t;
  359. };
  360. template <> struct __can_convert_char<char32_t> {
  361. static const bool value = true;
  362. using __char_type = char32_t;
  363. };
  364. template <class _ECharT>
  365. typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
  366. __is_separator(_ECharT __e) {
  367. return __e == _ECharT('/');
  368. };
  369. struct _NullSentinal {};
  370. template <class _Tp>
  371. using _Void = void;
  372. template <class _Tp, class = void>
  373. struct __is_pathable_string : public false_type {};
  374. template <class _ECharT, class _Traits, class _Alloc>
  375. struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
  376. _Void<typename __can_convert_char<_ECharT>::__char_type>>
  377. : public __can_convert_char<_ECharT>
  378. {
  379. using _Str = basic_string<_ECharT, _Traits, _Alloc>;
  380. using _Base = __can_convert_char<_ECharT>;
  381. static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
  382. static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
  383. static _ECharT __first_or_null(_Str const& __s) {
  384. return __s.empty() ? _ECharT{} : __s[0];
  385. }
  386. };
  387. template <class _Source,
  388. class _DS = typename decay<_Source>::type,
  389. class _UnqualPtrType = typename remove_const<
  390. typename remove_pointer<_DS>::type>::type,
  391. bool _IsCharPtr = is_pointer<_DS>::value &&
  392. __can_convert_char<_UnqualPtrType>::value
  393. >
  394. struct __is_pathable_char_array : false_type {};
  395. template <class _Source, class _ECharT, class _UPtr>
  396. struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
  397. : __can_convert_char<typename remove_const<_ECharT>::type>
  398. {
  399. using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
  400. static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
  401. static _ECharT const* __range_end(const _ECharT* __b)
  402. {
  403. using _Iter = const _ECharT*;
  404. const _ECharT __sentinal = _ECharT{};
  405. _Iter __e = __b;
  406. for (; *__e != __sentinal; ++__e)
  407. ;
  408. return __e;
  409. }
  410. static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
  411. };
  412. template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
  413. struct __is_pathable_iter : false_type {};
  414. template <class _Iter>
  415. struct __is_pathable_iter<_Iter, true,
  416. _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
  417. : __can_convert_char<typename iterator_traits<_Iter>::value_type>
  418. {
  419. using _ECharT = typename iterator_traits<_Iter>::value_type;
  420. using _Base = __can_convert_char<_ECharT>;
  421. static _Iter __range_begin(_Iter __b) { return __b; }
  422. static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
  423. static _ECharT __first_or_null(_Iter __b) { return *__b; }
  424. };
  425. template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
  426. bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
  427. bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
  428. >
  429. struct __is_pathable : false_type {
  430. static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
  431. };
  432. template <class _Tp>
  433. struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
  434. template <class _Tp>
  435. struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
  436. template <class _Tp>
  437. struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
  438. template <class _ECharT>
  439. struct _PathCVT {
  440. static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
  441. typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
  442. static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) {
  443. _Narrower()(back_inserter(__dest), __b, __e);
  444. }
  445. template <class _Iter>
  446. static void __append_range(string& __dest, _Iter __b, _Iter __e) {
  447. static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
  448. if (__b == __e) return;
  449. basic_string<_ECharT> __tmp(__b, __e);
  450. _Narrower()(back_inserter(__dest), __tmp.data(),
  451. __tmp.data() + __tmp.length());
  452. }
  453. template <class _Iter>
  454. static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
  455. static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
  456. const _ECharT __sentinal = _ECharT{};
  457. if (*__b == __sentinal) return;
  458. basic_string<_ECharT> __tmp;
  459. for (; *__b != __sentinal; ++__b)
  460. __tmp.push_back(*__b);
  461. _Narrower()(back_inserter(__dest), __tmp.data(),
  462. __tmp.data() + __tmp.length());
  463. }
  464. template <class _Source>
  465. static void __append_source(string& __dest, _Source const& __s)
  466. {
  467. using _Traits = __is_pathable<_Source>;
  468. __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
  469. }
  470. };
  471. template <>
  472. struct _PathCVT<char> {
  473. template <class _Iter>
  474. static void __append_range(string& __dest, _Iter __b, _Iter __e) {
  475. for (; __b != __e; ++__b)
  476. __dest.push_back(*__b);
  477. }
  478. template <class _Iter>
  479. static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
  480. const char __sentinal = char{};
  481. for (; *__b != __sentinal; ++__b)
  482. __dest.push_back(*__b);
  483. }
  484. template <class _Source>
  485. static void __append_source(string& __dest, _Source const& __s)
  486. {
  487. using _Traits = __is_pathable<_Source>;
  488. __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
  489. }
  490. };
  491. class _LIBCPP_TYPE_VIS path
  492. {
  493. template <class _SourceOrIter, class _Tp = path&>
  494. using _EnableIfPathable = typename
  495. enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
  496. template <class _Tp>
  497. using _SourceChar = typename __is_pathable<_Tp>::__char_type;
  498. template <class _Tp>
  499. using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
  500. public:
  501. typedef char value_type;
  502. typedef basic_string<value_type> string_type;
  503. static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
  504. // constructors and destructor
  505. _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
  506. _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
  507. _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
  508. _LIBCPP_INLINE_VISIBILITY
  509. path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {}
  510. template <
  511. class _Source,
  512. class = _EnableIfPathable<_Source, void>
  513. >
  514. path(const _Source& __src) {
  515. _SourceCVT<_Source>::__append_source(__pn_, __src);
  516. }
  517. template <class _InputIt>
  518. path(_InputIt __first, _InputIt __last) {
  519. typedef typename iterator_traits<_InputIt>::value_type _ItVal;
  520. _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
  521. }
  522. // TODO Implement locale conversions.
  523. template <class _Source,
  524. class = _EnableIfPathable<_Source, void>
  525. >
  526. path(const _Source& __src, const locale& __loc);
  527. template <class _InputIt>
  528. path(_InputIt __first, _InputIt _last, const locale& __loc);
  529. _LIBCPP_INLINE_VISIBILITY
  530. ~path() = default;
  531. // assignments
  532. _LIBCPP_INLINE_VISIBILITY
  533. path& operator=(const path& __p) {
  534. __pn_ = __p.__pn_;
  535. return *this;
  536. }
  537. _LIBCPP_INLINE_VISIBILITY
  538. path& operator=(path&& __p) _NOEXCEPT {
  539. __pn_ = _VSTD::move(__p.__pn_);
  540. return *this;
  541. }
  542. _LIBCPP_INLINE_VISIBILITY
  543. path& operator=(string_type&& __s) _NOEXCEPT {
  544. __pn_ = _VSTD::move(__s);
  545. return *this;
  546. }
  547. _LIBCPP_INLINE_VISIBILITY
  548. path& assign(string_type&& __s) _NOEXCEPT {
  549. __pn_ = _VSTD::move(__s);
  550. return *this;
  551. }
  552. template <class _Source>
  553. _LIBCPP_INLINE_VISIBILITY
  554. _EnableIfPathable<_Source>
  555. operator=(const _Source& __src)
  556. { return this->assign(__src); }
  557. template <class _Source>
  558. _EnableIfPathable<_Source>
  559. assign(const _Source& __src) {
  560. __pn_.clear();
  561. _SourceCVT<_Source>::__append_source(__pn_, __src);
  562. return *this;
  563. }
  564. template <class _InputIt>
  565. path& assign(_InputIt __first, _InputIt __last) {
  566. typedef typename iterator_traits<_InputIt>::value_type _ItVal;
  567. __pn_.clear();
  568. _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
  569. return *this;
  570. }
  571. private:
  572. template <class _ECharT>
  573. void __append_sep_if_needed(_ECharT __first_or_null) {
  574. const _ECharT __null_val = {};
  575. bool __append_sep = !empty() &&
  576. !__is_separator(__pn_.back()) &&
  577. __first_or_null != __null_val && // non-empty
  578. !__is_separator(__first_or_null);
  579. if (__append_sep)
  580. __pn_ += preferred_separator;
  581. }
  582. public:
  583. // appends
  584. path& operator/=(const path& __p) {
  585. __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
  586. __pn_ += __p.native();
  587. return *this;
  588. }
  589. template <class _Source>
  590. _LIBCPP_INLINE_VISIBILITY
  591. _EnableIfPathable<_Source>
  592. operator/=(const _Source& __src) {
  593. return this->append(__src);
  594. }
  595. template <class _Source>
  596. _EnableIfPathable<_Source>
  597. append(const _Source& __src) {
  598. using _Traits = __is_pathable<_Source>;
  599. using _CVT = _PathCVT<_SourceChar<_Source>>;
  600. __append_sep_if_needed(_Traits::__first_or_null(__src));
  601. _CVT::__append_source(__pn_, __src);
  602. return *this;
  603. }
  604. template <class _InputIt>
  605. path& append(_InputIt __first, _InputIt __last) {
  606. typedef typename iterator_traits<_InputIt>::value_type _ItVal;
  607. static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
  608. using _CVT = _PathCVT<_ItVal>;
  609. if (__first != __last) {
  610. __append_sep_if_needed(*__first);
  611. _CVT::__append_range(__pn_, __first, __last);
  612. }
  613. return *this;
  614. }
  615. // concatenation
  616. _LIBCPP_INLINE_VISIBILITY
  617. path& operator+=(const path& __x) {
  618. __pn_ += __x.__pn_;
  619. return *this;
  620. }
  621. _LIBCPP_INLINE_VISIBILITY
  622. path& operator+=(const string_type& __x) {
  623. __pn_ += __x;
  624. return *this;
  625. }
  626. _LIBCPP_INLINE_VISIBILITY
  627. path& operator+=(const value_type* __x) {
  628. __pn_ += __x;
  629. return *this;
  630. }
  631. _LIBCPP_INLINE_VISIBILITY
  632. path& operator+=(value_type __x) {
  633. __pn_ += __x;
  634. return *this;
  635. }
  636. template <class _ECharT>
  637. typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
  638. operator+=(_ECharT __x)
  639. {
  640. basic_string<_ECharT> __tmp;
  641. __tmp += __x;
  642. _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
  643. return *this;
  644. }
  645. template <class _Source>
  646. _EnableIfPathable<_Source>
  647. operator+=(const _Source& __x) {
  648. return this->concat(__x);
  649. }
  650. template <class _Source>
  651. _EnableIfPathable<_Source>
  652. concat(const _Source& __x) {
  653. _SourceCVT<_Source>::__append_source(__pn_, __x);
  654. return *this;
  655. }
  656. template <class _InputIt>
  657. path& concat(_InputIt __first, _InputIt __last) {
  658. typedef typename iterator_traits<_InputIt>::value_type _ItVal;
  659. _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
  660. return *this;
  661. }
  662. // modifiers
  663. _LIBCPP_INLINE_VISIBILITY
  664. void clear() _NOEXCEPT {
  665. __pn_.clear();
  666. }
  667. path& make_preferred() { return *this; }
  668. path& remove_filename() { return *this = parent_path(); }
  669. path& replace_filename(const path& __replacement) {
  670. remove_filename();
  671. return (*this /= __replacement);
  672. }
  673. path& replace_extension(const path& __replacement = path());
  674. _LIBCPP_INLINE_VISIBILITY
  675. void swap(path& __rhs) _NOEXCEPT {
  676. __pn_.swap(__rhs.__pn_);
  677. }
  678. // native format observers
  679. _LIBCPP_INLINE_VISIBILITY
  680. const string_type& native() const _NOEXCEPT {
  681. return __pn_;
  682. }
  683. _LIBCPP_INLINE_VISIBILITY
  684. const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
  685. _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
  686. template <class _ECharT, class _Traits = char_traits<_ECharT>,
  687. class _Allocator = allocator<_ECharT> >
  688. basic_string<_ECharT, _Traits, _Allocator>
  689. string(const _Allocator& __a = _Allocator()) const {
  690. using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
  691. using _Str = basic_string<_ECharT, _Traits, _Allocator>;
  692. _Str __s(__a);
  693. __s.reserve(__pn_.size());
  694. _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
  695. return __s;
  696. }
  697. _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
  698. _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); }
  699. _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
  700. _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
  701. _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
  702. // generic format observers
  703. template <class _ECharT, class _Traits = char_traits<_ECharT>,
  704. class _Allocator = allocator<_ECharT>
  705. >
  706. basic_string<_ECharT, _Traits, _Allocator>
  707. generic_string(const _Allocator& __a = _Allocator()) const {
  708. return string<_ECharT, _Traits, _Allocator>(__a);
  709. }
  710. std::string generic_string() const { return __pn_; }
  711. std::wstring generic_wstring() const { return string<wchar_t>(); }
  712. std::string generic_u8string() const { return __pn_; }
  713. std::u16string generic_u16string() const { return string<char16_t>(); }
  714. std::u32string generic_u32string() const { return string<char32_t>(); }
  715. private:
  716. _LIBCPP_FUNC_VIS int __compare(const value_type*) const;
  717. _LIBCPP_FUNC_VIS string_view __root_name() const;
  718. _LIBCPP_FUNC_VIS string_view __root_directory() const;
  719. _LIBCPP_FUNC_VIS string_view __relative_path() const;
  720. _LIBCPP_FUNC_VIS string_view __parent_path() const;
  721. _LIBCPP_FUNC_VIS string_view __filename() const;
  722. _LIBCPP_FUNC_VIS string_view __stem() const;
  723. _LIBCPP_FUNC_VIS string_view __extension() const;
  724. public:
  725. // compare
  726. _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.c_str());}
  727. _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s.c_str()); }
  728. _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
  729. // decomposition
  730. _LIBCPP_INLINE_VISIBILITY path root_name() const { return __root_name().to_string(); }
  731. _LIBCPP_INLINE_VISIBILITY path root_directory() const { return __root_directory().to_string(); }
  732. _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(__root_directory().to_string()); }
  733. _LIBCPP_INLINE_VISIBILITY path relative_path() const { return __relative_path().to_string(); }
  734. _LIBCPP_INLINE_VISIBILITY path parent_path() const { return __parent_path().to_string(); }
  735. _LIBCPP_INLINE_VISIBILITY path filename() const { return __filename().to_string(); }
  736. _LIBCPP_INLINE_VISIBILITY path stem() const { return __stem().to_string();}
  737. _LIBCPP_INLINE_VISIBILITY path extension() const { return __extension().to_string(); }
  738. // query
  739. _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT { return __pn_.empty(); }
  740. _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); }
  741. _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
  742. _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !(__root_name().empty() && __root_directory().empty()); }
  743. _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); }
  744. _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); }
  745. _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); }
  746. _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
  747. _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); }
  748. _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
  749. _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
  750. // iterators
  751. class _LIBCPP_TYPE_VIS iterator;
  752. typedef iterator const_iterator;
  753. _LIBCPP_FUNC_VIS iterator begin() const;
  754. _LIBCPP_FUNC_VIS iterator end() const;
  755. private:
  756. inline _LIBCPP_INLINE_VISIBILITY
  757. path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; }
  758. string_type __pn_;
  759. };
  760. inline _LIBCPP_ALWAYS_INLINE
  761. void swap(path& __lhs, path& __rhs) _NOEXCEPT {
  762. __lhs.swap(__rhs);
  763. }
  764. _LIBCPP_FUNC_VIS
  765. size_t hash_value(const path& __p) _NOEXCEPT;
  766. inline _LIBCPP_INLINE_VISIBILITY
  767. bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
  768. { return __lhs.compare(__rhs) == 0; }
  769. inline _LIBCPP_INLINE_VISIBILITY
  770. bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
  771. { return __lhs.compare(__rhs) != 0; }
  772. inline _LIBCPP_INLINE_VISIBILITY
  773. bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
  774. { return __lhs.compare(__rhs) < 0; }
  775. inline _LIBCPP_INLINE_VISIBILITY
  776. bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
  777. { return __lhs.compare(__rhs) <= 0; }
  778. inline _LIBCPP_INLINE_VISIBILITY
  779. bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
  780. { return __lhs.compare(__rhs) > 0; }
  781. inline _LIBCPP_INLINE_VISIBILITY
  782. bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
  783. { return __lhs.compare(__rhs) >= 0; }
  784. inline _LIBCPP_INLINE_VISIBILITY
  785. path operator/(const path& __lhs, const path& __rhs) {
  786. return path(__lhs) /= __rhs;
  787. }
  788. template <class _CharT, class _Traits>
  789. _LIBCPP_INLINE_VISIBILITY
  790. typename enable_if<is_same<_CharT, char>::value &&
  791. is_same<_Traits, char_traits<char>>::value,
  792. basic_ostream<_CharT, _Traits>&
  793. >::type
  794. operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
  795. __os << std::__quoted(__p.native());
  796. return __os;
  797. }
  798. template <class _CharT, class _Traits>
  799. _LIBCPP_INLINE_VISIBILITY
  800. typename enable_if<!is_same<_CharT, char>::value ||
  801. !is_same<_Traits, char_traits<char>>::value,
  802. basic_ostream<_CharT, _Traits>&
  803. >::type
  804. operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
  805. __os << std::__quoted(__p.string<_CharT, _Traits>());
  806. return __os;
  807. }
  808. template <class _CharT, class _Traits>
  809. _LIBCPP_INLINE_VISIBILITY
  810. basic_istream<_CharT, _Traits>&
  811. operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
  812. {
  813. basic_string<_CharT, _Traits> __tmp;
  814. __is >> __quoted(__tmp);
  815. __p = __tmp;
  816. return __is;
  817. }
  818. template <class _Source>
  819. _LIBCPP_INLINE_VISIBILITY
  820. typename enable_if<__is_pathable<_Source>::value, path>::type
  821. u8path(const _Source& __s){
  822. static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
  823. "u8path(Source const&) requires Source have a character type of type 'char'");
  824. return path(__s);
  825. }
  826. template <class _InputIt>
  827. _LIBCPP_INLINE_VISIBILITY
  828. typename enable_if<__is_pathable<_InputIt>::value, path>::type
  829. u8path(_InputIt __f, _InputIt __l) {
  830. static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
  831. "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
  832. return path(__f, __l);
  833. }
  834. class _LIBCPP_TYPE_VIS path::iterator
  835. {
  836. public:
  837. typedef bidirectional_iterator_tag iterator_category;
  838. typedef path value_type;
  839. typedef std::ptrdiff_t difference_type;
  840. typedef const path* pointer;
  841. typedef const path& reference;
  842. public:
  843. _LIBCPP_INLINE_VISIBILITY
  844. iterator() : __elem_(), __path_ptr_(nullptr), __pos_(0) {}
  845. iterator(const iterator&) = default;
  846. ~iterator() = default;
  847. iterator& operator=(const iterator&) = default;
  848. _LIBCPP_INLINE_VISIBILITY
  849. reference operator*() const {
  850. return __elem_;
  851. }
  852. _LIBCPP_INLINE_VISIBILITY
  853. pointer operator->() const {
  854. return &__elem_;
  855. }
  856. _LIBCPP_INLINE_VISIBILITY
  857. iterator& operator++() {
  858. return __increment();
  859. }
  860. _LIBCPP_INLINE_VISIBILITY
  861. iterator operator++(int) {
  862. iterator __it(*this);
  863. this->operator++();
  864. return __it;
  865. }
  866. _LIBCPP_INLINE_VISIBILITY
  867. iterator& operator--() {
  868. return __decrement();
  869. }
  870. _LIBCPP_INLINE_VISIBILITY
  871. iterator operator--(int) {
  872. iterator __it(*this);
  873. this->operator--();
  874. return __it;
  875. }
  876. private:
  877. friend class path;
  878. friend bool operator==(const iterator&, const iterator&);
  879. _LIBCPP_FUNC_VIS iterator& __increment();
  880. _LIBCPP_FUNC_VIS iterator& __decrement();
  881. path __elem_;
  882. const path* __path_ptr_;
  883. size_t __pos_;
  884. };
  885. inline _LIBCPP_INLINE_VISIBILITY
  886. bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
  887. return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
  888. __lhs.__pos_ == __rhs.__pos_;
  889. }
  890. inline _LIBCPP_INLINE_VISIBILITY
  891. bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
  892. return !(__lhs == __rhs);
  893. }
  894. class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
  895. {
  896. public:
  897. _LIBCPP_INLINE_VISIBILITY
  898. filesystem_error(const string& __what, error_code __ec)
  899. : system_error(__ec, __what),
  900. __paths_(make_shared<_Storage>(path(), path()))
  901. {}
  902. _LIBCPP_INLINE_VISIBILITY
  903. filesystem_error(const string& __what, const path& __p1, error_code __ec)
  904. : system_error(__ec, __what),
  905. __paths_(make_shared<_Storage>(__p1, path()))
  906. {}
  907. _LIBCPP_INLINE_VISIBILITY
  908. filesystem_error(const string& __what, const path& __p1, const path& __p2,
  909. error_code __ec)
  910. : system_error(__ec, __what),
  911. __paths_(make_shared<_Storage>(__p1, __p2))
  912. {}
  913. _LIBCPP_INLINE_VISIBILITY
  914. const path& path1() const _NOEXCEPT {
  915. return __paths_->first;
  916. }
  917. _LIBCPP_INLINE_VISIBILITY
  918. const path& path2() const _NOEXCEPT {
  919. return __paths_->second;
  920. }
  921. _LIBCPP_FUNC_VIS
  922. ~filesystem_error() override; // key function
  923. // TODO(ericwf): Create a custom error message.
  924. //const char* what() const _NOEXCEPT;
  925. private:
  926. typedef pair<path, path> _Storage;
  927. shared_ptr<_Storage> __paths_;
  928. };
  929. // operational functions
  930. _LIBCPP_FUNC_VIS
  931. path __canonical(const path&, const path&, error_code *__ec=nullptr);
  932. _LIBCPP_FUNC_VIS
  933. void __copy(const path& __from, const path& __to, copy_options __opt,
  934. error_code *__ec=nullptr);
  935. _LIBCPP_FUNC_VIS
  936. bool __copy_file(const path& __from, const path& __to, copy_options __opt,
  937. error_code *__ec=nullptr);
  938. _LIBCPP_FUNC_VIS
  939. void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
  940. error_code *__ec=nullptr);
  941. _LIBCPP_FUNC_VIS
  942. bool __create_directories(const path& p, error_code *ec=nullptr);
  943. _LIBCPP_FUNC_VIS
  944. bool __create_directory(const path& p, error_code *ec=nullptr);
  945. _LIBCPP_FUNC_VIS
  946. bool __create_directory(const path& p, const path & attributes,
  947. error_code *ec=nullptr);
  948. _LIBCPP_FUNC_VIS
  949. void __create_directory_symlink(const path& __to, const path& __new_symlink,
  950. error_code *__ec=nullptr);
  951. _LIBCPP_FUNC_VIS
  952. void __create_hard_link(const path& __to, const path& __new_hard_link,
  953. error_code *__ec=nullptr);
  954. _LIBCPP_FUNC_VIS
  955. void __create_symlink(const path& __to, const path& __new_symlink,
  956. error_code *__ec=nullptr);
  957. _LIBCPP_FUNC_VIS
  958. path __current_path(error_code *__ec=nullptr);
  959. _LIBCPP_FUNC_VIS
  960. void __current_path(const path&, error_code *__ec=nullptr);
  961. _LIBCPP_FUNC_VIS
  962. bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
  963. _LIBCPP_FUNC_VIS
  964. uintmax_t __file_size(const path&, error_code *__ec=nullptr);
  965. _LIBCPP_FUNC_VIS
  966. uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
  967. _LIBCPP_FUNC_VIS
  968. bool __fs_is_empty(const path& p, error_code *ec=nullptr);
  969. _LIBCPP_FUNC_VIS
  970. file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
  971. _LIBCPP_FUNC_VIS
  972. void __last_write_time(const path& p, file_time_type new_time,
  973. error_code *ec=nullptr);
  974. _LIBCPP_FUNC_VIS
  975. void __permissions(const path& p, perms prms, error_code *ec=nullptr);
  976. _LIBCPP_FUNC_VIS
  977. path __read_symlink(const path& p, error_code *ec=nullptr);
  978. _LIBCPP_FUNC_VIS
  979. bool __remove(const path& p, error_code *ec=nullptr);
  980. _LIBCPP_FUNC_VIS
  981. uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
  982. _LIBCPP_FUNC_VIS
  983. void __rename(const path& from, const path& to, error_code *ec=nullptr);
  984. _LIBCPP_FUNC_VIS
  985. void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
  986. _LIBCPP_FUNC_VIS
  987. space_info __space(const path&, error_code *__ec=nullptr);
  988. _LIBCPP_FUNC_VIS
  989. file_status __status(const path&, error_code *__ec=nullptr);
  990. _LIBCPP_FUNC_VIS
  991. file_status __symlink_status(const path&, error_code *__ec=nullptr);
  992. _LIBCPP_FUNC_VIS
  993. path __system_complete(const path&, error_code *__ec=nullptr);
  994. _LIBCPP_FUNC_VIS
  995. path __temp_directory_path(error_code *__ec=nullptr);
  996. inline _LIBCPP_INLINE_VISIBILITY
  997. path current_path() {
  998. return __current_path();
  999. }
  1000. inline _LIBCPP_INLINE_VISIBILITY
  1001. path current_path(error_code& __ec) {
  1002. return __current_path(&__ec);
  1003. }
  1004. inline _LIBCPP_INLINE_VISIBILITY
  1005. void current_path(const path& __p) {
  1006. __current_path(__p);
  1007. }
  1008. inline _LIBCPP_INLINE_VISIBILITY
  1009. void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
  1010. __current_path(__p, &__ec);
  1011. }
  1012. _LIBCPP_FUNC_VIS
  1013. path absolute(const path&, const path& __p2 = current_path());
  1014. inline _LIBCPP_INLINE_VISIBILITY
  1015. path canonical(const path& __p, const path& __base = current_path()) {
  1016. return __canonical(__p, __base);
  1017. }
  1018. inline _LIBCPP_INLINE_VISIBILITY
  1019. path canonical(const path& __p, error_code& __ec) {
  1020. path __base = __current_path(&__ec);
  1021. if (__ec) return {};
  1022. return __canonical(__p, __base, &__ec);
  1023. }
  1024. inline _LIBCPP_INLINE_VISIBILITY
  1025. path canonical(const path& __p, const path& __base, error_code& __ec) {
  1026. return __canonical(__p, __base, &__ec);
  1027. }
  1028. inline _LIBCPP_INLINE_VISIBILITY
  1029. void copy(const path& __from, const path& __to) {
  1030. __copy(__from, __to, copy_options::none);
  1031. }
  1032. inline _LIBCPP_INLINE_VISIBILITY
  1033. void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
  1034. __copy(__from, __to, copy_options::none, &__ec);
  1035. }
  1036. inline _LIBCPP_INLINE_VISIBILITY
  1037. void copy(const path& __from, const path& __to, copy_options __opt) {
  1038. __copy(__from, __to, __opt);
  1039. }
  1040. inline _LIBCPP_INLINE_VISIBILITY
  1041. void copy(const path& __from, const path& __to,
  1042. copy_options __opt, error_code& __ec) _NOEXCEPT {
  1043. __copy(__from, __to, __opt, &__ec);
  1044. }
  1045. inline _LIBCPP_INLINE_VISIBILITY
  1046. bool copy_file(const path& __from, const path& __to) {
  1047. return __copy_file(__from, __to, copy_options::none);
  1048. }
  1049. inline _LIBCPP_INLINE_VISIBILITY
  1050. bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
  1051. return __copy_file(__from, __to, copy_options::none, &__ec);
  1052. }
  1053. inline _LIBCPP_INLINE_VISIBILITY
  1054. bool copy_file(const path& __from, const path& __to, copy_options __opt) {
  1055. return __copy_file(__from, __to, __opt);
  1056. }
  1057. inline _LIBCPP_INLINE_VISIBILITY
  1058. bool copy_file(const path& __from, const path& __to,
  1059. copy_options __opt, error_code& __ec) _NOEXCEPT {
  1060. return __copy_file(__from, __to, __opt, &__ec);
  1061. }
  1062. inline _LIBCPP_INLINE_VISIBILITY
  1063. void copy_symlink(const path& __existing, const path& __new) {
  1064. __copy_symlink(__existing, __new);
  1065. }
  1066. inline _LIBCPP_INLINE_VISIBILITY
  1067. void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
  1068. __copy_symlink(__ext, __new, &__ec);
  1069. }
  1070. inline _LIBCPP_INLINE_VISIBILITY
  1071. bool create_directories(const path& __p) {
  1072. return __create_directories(__p);
  1073. }
  1074. inline _LIBCPP_INLINE_VISIBILITY
  1075. bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT {
  1076. return __create_directories(__p, &__ec);
  1077. }
  1078. inline _LIBCPP_INLINE_VISIBILITY
  1079. bool create_directory(const path& __p) {
  1080. return __create_directory(__p);
  1081. }
  1082. inline _LIBCPP_INLINE_VISIBILITY
  1083. bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
  1084. return __create_directory(__p, &__ec);
  1085. }
  1086. inline _LIBCPP_INLINE_VISIBILITY
  1087. bool create_directory(const path& __p, const path& __attrs) {
  1088. return __create_directory(__p, __attrs);
  1089. }
  1090. inline _LIBCPP_INLINE_VISIBILITY
  1091. bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
  1092. return __create_directory(__p, __attrs, &__ec);
  1093. }
  1094. inline _LIBCPP_INLINE_VISIBILITY
  1095. void create_directory_symlink(const path& __to, const path& __new) {
  1096. __create_directory_symlink(__to, __new);
  1097. }
  1098. inline _LIBCPP_INLINE_VISIBILITY
  1099. void create_directory_symlink(const path& __to, const path& __new,
  1100. error_code& __ec) _NOEXCEPT {
  1101. __create_directory_symlink(__to, __new, &__ec);
  1102. }
  1103. inline _LIBCPP_INLINE_VISIBILITY
  1104. void create_hard_link(const path& __to, const path& __new) {
  1105. __create_hard_link(__to, __new);
  1106. }
  1107. inline _LIBCPP_INLINE_VISIBILITY
  1108. void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
  1109. __create_hard_link(__to, __new, &__ec);
  1110. }
  1111. inline _LIBCPP_INLINE_VISIBILITY
  1112. void create_symlink(const path& __to, const path& __new) {
  1113. __create_symlink(__to, __new);
  1114. }
  1115. inline _LIBCPP_INLINE_VISIBILITY
  1116. void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
  1117. return __create_symlink(__to, __new, &__ec);
  1118. }
  1119. inline _LIBCPP_INLINE_VISIBILITY
  1120. bool status_known(file_status __s) _NOEXCEPT {
  1121. return __s.type() != file_type::none;
  1122. }
  1123. inline _LIBCPP_INLINE_VISIBILITY
  1124. bool exists(file_status __s) _NOEXCEPT {
  1125. return status_known(__s) && __s.type() != file_type::not_found;
  1126. }
  1127. inline _LIBCPP_INLINE_VISIBILITY
  1128. bool exists(const path& __p) {
  1129. return exists(__status(__p));
  1130. }
  1131. inline _LIBCPP_INLINE_VISIBILITY
  1132. bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
  1133. auto __s = __status(__p, &__ec);
  1134. if (status_known(__s)) __ec.clear();
  1135. return exists(__s);
  1136. }
  1137. inline _LIBCPP_INLINE_VISIBILITY
  1138. bool equivalent(const path& __p1, const path& __p2) {
  1139. return __equivalent(__p1, __p2);
  1140. }
  1141. inline _LIBCPP_INLINE_VISIBILITY
  1142. bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
  1143. return __equivalent(__p1, __p2, &__ec);
  1144. }
  1145. inline _LIBCPP_INLINE_VISIBILITY
  1146. uintmax_t file_size(const path& __p) {
  1147. return __file_size(__p);
  1148. }
  1149. inline _LIBCPP_INLINE_VISIBILITY
  1150. uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
  1151. return __file_size(__p, &__ec);
  1152. }
  1153. inline _LIBCPP_INLINE_VISIBILITY
  1154. uintmax_t hard_link_count(const path& __p) {
  1155. return __hard_link_count(__p);
  1156. }
  1157. inline _LIBCPP_INLINE_VISIBILITY
  1158. uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
  1159. return __hard_link_count(__p, &__ec);
  1160. }
  1161. inline _LIBCPP_INLINE_VISIBILITY
  1162. bool is_block_file(file_status __s) _NOEXCEPT {
  1163. return __s.type() == file_type::block;
  1164. }
  1165. inline _LIBCPP_INLINE_VISIBILITY
  1166. bool is_block_file(const path& __p) {
  1167. return is_block_file(__status(__p));
  1168. }
  1169. inline _LIBCPP_INLINE_VISIBILITY
  1170. bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
  1171. return is_block_file(__status(__p, &__ec));
  1172. }
  1173. inline _LIBCPP_INLINE_VISIBILITY
  1174. bool is_character_file(file_status __s) _NOEXCEPT {
  1175. return __s.type() == file_type::character;
  1176. }
  1177. inline _LIBCPP_INLINE_VISIBILITY
  1178. bool is_character_file(const path& __p) {
  1179. return is_character_file(__status(__p));
  1180. }
  1181. inline _LIBCPP_INLINE_VISIBILITY
  1182. bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
  1183. return is_character_file(__status(__p, &__ec));
  1184. }
  1185. inline _LIBCPP_INLINE_VISIBILITY
  1186. bool is_directory(file_status __s) _NOEXCEPT {
  1187. return __s.type() == file_type::directory;
  1188. }
  1189. inline _LIBCPP_INLINE_VISIBILITY
  1190. bool is_directory(const path& __p) {
  1191. return is_directory(__status(__p));
  1192. }
  1193. inline _LIBCPP_INLINE_VISIBILITY
  1194. bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
  1195. return is_directory(__status(__p, &__ec));
  1196. }
  1197. inline _LIBCPP_INLINE_VISIBILITY
  1198. bool is_empty(const path& __p) {
  1199. return __fs_is_empty(__p);
  1200. }
  1201. inline _LIBCPP_INLINE_VISIBILITY
  1202. bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT {
  1203. return __fs_is_empty(__p, &__ec);
  1204. }
  1205. inline _LIBCPP_INLINE_VISIBILITY
  1206. bool is_fifo(file_status __s) _NOEXCEPT {
  1207. return __s.type() == file_type::fifo;
  1208. }
  1209. inline _LIBCPP_INLINE_VISIBILITY
  1210. bool is_fifo(const path& __p) {
  1211. return is_fifo(__status(__p));
  1212. }
  1213. inline _LIBCPP_INLINE_VISIBILITY
  1214. bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
  1215. return is_fifo(__status(__p, &__ec));
  1216. }
  1217. inline _LIBCPP_INLINE_VISIBILITY
  1218. bool is_regular_file(file_status __s) _NOEXCEPT {
  1219. return __s.type() == file_type::regular;
  1220. }
  1221. inline _LIBCPP_INLINE_VISIBILITY
  1222. bool is_regular_file(const path& __p) {
  1223. return is_regular_file(__status(__p));
  1224. }
  1225. inline _LIBCPP_INLINE_VISIBILITY
  1226. bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
  1227. return is_regular_file(__status(__p, &__ec));
  1228. }
  1229. inline _LIBCPP_INLINE_VISIBILITY
  1230. bool is_socket(file_status __s) _NOEXCEPT {
  1231. return __s.type() == file_type::socket;
  1232. }
  1233. inline _LIBCPP_INLINE_VISIBILITY
  1234. bool is_socket(const path& __p) {
  1235. return is_socket(__status(__p));
  1236. }
  1237. inline _LIBCPP_INLINE_VISIBILITY
  1238. bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
  1239. return is_socket(__status(__p, &__ec));
  1240. }
  1241. inline _LIBCPP_INLINE_VISIBILITY
  1242. bool is_symlink(file_status __s) _NOEXCEPT {
  1243. return __s.type() == file_type::symlink;
  1244. }
  1245. inline _LIBCPP_INLINE_VISIBILITY
  1246. bool is_symlink(const path& __p) {
  1247. return is_symlink(__symlink_status(__p));
  1248. }
  1249. inline _LIBCPP_INLINE_VISIBILITY
  1250. bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
  1251. return is_symlink(__symlink_status(__p, &__ec));
  1252. }
  1253. inline _LIBCPP_INLINE_VISIBILITY
  1254. bool is_other(file_status __s) _NOEXCEPT {
  1255. return exists(__s)
  1256. && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
  1257. }
  1258. inline _LIBCPP_INLINE_VISIBILITY
  1259. bool is_other(const path& __p) {
  1260. return is_other(__status(__p));
  1261. }
  1262. inline _LIBCPP_INLINE_VISIBILITY
  1263. bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
  1264. return is_other(__status(__p, &__ec));
  1265. }
  1266. inline _LIBCPP_INLINE_VISIBILITY
  1267. file_time_type last_write_time(const path& __p) {
  1268. return __last_write_time(__p);
  1269. }
  1270. inline _LIBCPP_INLINE_VISIBILITY
  1271. file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
  1272. return __last_write_time(__p, &__ec);
  1273. }
  1274. inline _LIBCPP_INLINE_VISIBILITY
  1275. void last_write_time(const path& __p, file_time_type __t) {
  1276. __last_write_time(__p, __t);
  1277. }
  1278. inline _LIBCPP_INLINE_VISIBILITY
  1279. void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
  1280. __last_write_time(__p, __t, &__ec);
  1281. }
  1282. inline _LIBCPP_INLINE_VISIBILITY
  1283. void permissions(const path& __p, perms __prms) {
  1284. __permissions(__p, __prms);
  1285. }
  1286. inline _LIBCPP_INLINE_VISIBILITY
  1287. void permissions(const path& __p, perms __prms, error_code& __ec) {
  1288. __permissions(__p, __prms, &__ec);
  1289. }
  1290. inline _LIBCPP_INLINE_VISIBILITY
  1291. path read_symlink(const path& __p) {
  1292. return __read_symlink(__p);
  1293. }
  1294. inline _LIBCPP_INLINE_VISIBILITY
  1295. path read_symlink(const path& __p, error_code& __ec) {
  1296. return __read_symlink(__p, &__ec);
  1297. }
  1298. inline _LIBCPP_INLINE_VISIBILITY
  1299. bool remove(const path& __p) {
  1300. return __remove(__p);
  1301. }
  1302. inline _LIBCPP_INLINE_VISIBILITY
  1303. bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
  1304. return __remove(__p, &__ec);
  1305. }
  1306. inline _LIBCPP_INLINE_VISIBILITY
  1307. uintmax_t remove_all(const path& __p) {
  1308. return __remove_all(__p);
  1309. }
  1310. inline _LIBCPP_INLINE_VISIBILITY
  1311. uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT {
  1312. return __remove_all(__p, &__ec);
  1313. }
  1314. inline _LIBCPP_INLINE_VISIBILITY
  1315. void rename(const path& __from, const path& __to) {
  1316. return __rename(__from, __to);
  1317. }
  1318. inline _LIBCPP_INLINE_VISIBILITY
  1319. void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
  1320. return __rename(__from, __to, &__ec);
  1321. }
  1322. inline _LIBCPP_INLINE_VISIBILITY
  1323. void resize_file(const path& __p, uintmax_t __ns) {
  1324. return __resize_file(__p, __ns);
  1325. }
  1326. inline _LIBCPP_INLINE_VISIBILITY
  1327. void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
  1328. return __resize_file(__p, __ns, &__ec);
  1329. }
  1330. inline _LIBCPP_INLINE_VISIBILITY
  1331. space_info space(const path& __p) {
  1332. return __space(__p);
  1333. }
  1334. inline _LIBCPP_INLINE_VISIBILITY
  1335. space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
  1336. return __space(__p, &__ec);
  1337. }
  1338. inline _LIBCPP_INLINE_VISIBILITY
  1339. file_status status(const path& __p) {
  1340. return __status(__p);
  1341. }
  1342. inline _LIBCPP_INLINE_VISIBILITY
  1343. file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
  1344. return __status(__p, &__ec);
  1345. }
  1346. inline _LIBCPP_INLINE_VISIBILITY
  1347. file_status symlink_status(const path& __p) {
  1348. return __symlink_status(__p);
  1349. }
  1350. inline _LIBCPP_INLINE_VISIBILITY
  1351. file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
  1352. return __symlink_status(__p, &__ec);
  1353. }
  1354. inline _LIBCPP_INLINE_VISIBILITY
  1355. path system_complete(const path& __p) {
  1356. return __system_complete(__p);
  1357. }
  1358. inline _LIBCPP_INLINE_VISIBILITY
  1359. path system_complete(const path& __p, error_code& __ec) {
  1360. return __system_complete(__p, &__ec);
  1361. }
  1362. inline _LIBCPP_INLINE_VISIBILITY
  1363. path temp_directory_path() {
  1364. return __temp_directory_path();
  1365. }
  1366. inline _LIBCPP_INLINE_VISIBILITY
  1367. path temp_directory_path(error_code& __ec) {
  1368. return __temp_directory_path(&__ec);
  1369. }
  1370. class directory_entry
  1371. {
  1372. typedef _VSTD_FS::path _Path;
  1373. public:
  1374. // constructors and destructors
  1375. directory_entry() _NOEXCEPT = default;
  1376. directory_entry(directory_entry const&) = default;
  1377. directory_entry(directory_entry&&) _NOEXCEPT = default;
  1378. _LIBCPP_INLINE_VISIBILITY
  1379. explicit directory_entry(_Path const& __p) : __p_(__p) {}
  1380. ~directory_entry() {}
  1381. directory_entry& operator=(directory_entry const&) = default;
  1382. directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
  1383. _LIBCPP_INLINE_VISIBILITY
  1384. void assign(_Path const& __p) {
  1385. __p_ = __p;
  1386. }
  1387. _LIBCPP_INLINE_VISIBILITY
  1388. void replace_filename(_Path const& __p) {
  1389. __p_ = __p_.parent_path() / __p;
  1390. }
  1391. _LIBCPP_INLINE_VISIBILITY
  1392. _Path const& path() const _NOEXCEPT {
  1393. return __p_;
  1394. }
  1395. _LIBCPP_INLINE_VISIBILITY
  1396. operator const _Path&() const _NOEXCEPT {
  1397. return __p_;
  1398. }
  1399. _LIBCPP_INLINE_VISIBILITY
  1400. file_status status() const {
  1401. return _VSTD_FS::status(__p_);
  1402. }
  1403. _LIBCPP_INLINE_VISIBILITY
  1404. file_status status(error_code& __ec) const _NOEXCEPT {
  1405. return _VSTD_FS::status(__p_, __ec);
  1406. }
  1407. _LIBCPP_INLINE_VISIBILITY
  1408. file_status symlink_status() const {
  1409. return _VSTD_FS::symlink_status(__p_);
  1410. }
  1411. _LIBCPP_INLINE_VISIBILITY
  1412. file_status symlink_status(error_code& __ec) const _NOEXCEPT {
  1413. return _VSTD_FS::symlink_status(__p_, __ec);
  1414. }
  1415. _LIBCPP_INLINE_VISIBILITY
  1416. bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
  1417. return __p_ < __rhs.__p_;
  1418. }
  1419. _LIBCPP_INLINE_VISIBILITY
  1420. bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
  1421. return __p_ == __rhs.__p_;
  1422. }
  1423. _LIBCPP_INLINE_VISIBILITY
  1424. bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
  1425. return __p_ != __rhs.__p_;
  1426. }
  1427. _LIBCPP_INLINE_VISIBILITY
  1428. bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
  1429. return __p_ <= __rhs.__p_;
  1430. }
  1431. _LIBCPP_INLINE_VISIBILITY
  1432. bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
  1433. return __p_ > __rhs.__p_;
  1434. }
  1435. _LIBCPP_INLINE_VISIBILITY
  1436. bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
  1437. return __p_ >= __rhs.__p_;
  1438. }
  1439. private:
  1440. _Path __p_;
  1441. };
  1442. class directory_iterator;
  1443. class recursive_directory_iterator;
  1444. class __dir_stream;
  1445. class __dir_element_proxy {
  1446. public:
  1447. inline _LIBCPP_INLINE_VISIBILITY
  1448. directory_entry operator*() { return _VSTD::move(__elem_); }
  1449. private:
  1450. friend class directory_iterator;
  1451. friend class recursive_directory_iterator;
  1452. explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
  1453. __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
  1454. directory_entry __elem_;
  1455. };
  1456. class directory_iterator
  1457. {
  1458. public:
  1459. typedef directory_entry value_type;
  1460. typedef ptrdiff_t difference_type;
  1461. typedef value_type const* pointer;
  1462. typedef value_type const& reference;
  1463. typedef input_iterator_tag iterator_category;
  1464. public:
  1465. //ctor & dtor
  1466. directory_iterator() _NOEXCEPT
  1467. { }
  1468. explicit directory_iterator(const path& __p)
  1469. : directory_iterator(__p, nullptr)
  1470. { }
  1471. directory_iterator(const path& __p, directory_options __opts)
  1472. : directory_iterator(__p, nullptr, __opts)
  1473. { }
  1474. directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
  1475. : directory_iterator(__p, &__ec)
  1476. { }
  1477. directory_iterator(const path& __p, directory_options __opts,
  1478. error_code& __ec) _NOEXCEPT
  1479. : directory_iterator(__p, &__ec, __opts)
  1480. { }
  1481. directory_iterator(const directory_iterator&) = default;
  1482. directory_iterator(directory_iterator&&) = default;
  1483. directory_iterator& operator=(const directory_iterator&) = default;
  1484. directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
  1485. // non-default implementation provided to support self-move assign.
  1486. if (this != &__o) {
  1487. __imp_ = _VSTD::move(__o.__imp_);
  1488. }
  1489. return *this;
  1490. }
  1491. ~directory_iterator() = default;
  1492. const directory_entry& operator*() const {
  1493. _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
  1494. return __deref();
  1495. }
  1496. const directory_entry* operator->() const
  1497. { return &**this; }
  1498. directory_iterator& operator++()
  1499. { return __increment(); }
  1500. __dir_element_proxy operator++(int) {
  1501. __dir_element_proxy __p(**this);
  1502. __increment();
  1503. return __p;
  1504. }
  1505. directory_iterator& increment(error_code& __ec) _NOEXCEPT
  1506. { return __increment(&__ec); }
  1507. private:
  1508. friend bool operator==(const directory_iterator& __lhs,
  1509. const directory_iterator& __rhs) _NOEXCEPT;
  1510. // construct the dir_stream
  1511. _LIBCPP_FUNC_VIS
  1512. directory_iterator(const path&, error_code *, directory_options = directory_options::none);
  1513. _LIBCPP_FUNC_VIS
  1514. directory_iterator& __increment(error_code * __ec = nullptr);
  1515. _LIBCPP_FUNC_VIS
  1516. const directory_entry& __deref() const;
  1517. private:
  1518. shared_ptr<__dir_stream> __imp_;
  1519. };
  1520. inline _LIBCPP_INLINE_VISIBILITY
  1521. bool operator==(const directory_iterator& __lhs,
  1522. const directory_iterator& __rhs) _NOEXCEPT {
  1523. return __lhs.__imp_ == __rhs.__imp_;
  1524. }
  1525. inline _LIBCPP_INLINE_VISIBILITY
  1526. bool operator!=(const directory_iterator& __lhs,
  1527. const directory_iterator& __rhs) _NOEXCEPT {
  1528. return !(__lhs == __rhs);
  1529. }
  1530. // enable directory_iterator range-based for statements
  1531. inline _LIBCPP_INLINE_VISIBILITY
  1532. directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
  1533. return __iter;
  1534. }
  1535. inline _LIBCPP_INLINE_VISIBILITY
  1536. directory_iterator end(const directory_iterator&) _NOEXCEPT {
  1537. return directory_iterator();
  1538. }
  1539. class recursive_directory_iterator {
  1540. public:
  1541. using value_type = directory_entry;
  1542. using difference_type = std::ptrdiff_t;
  1543. using pointer = directory_entry const *;
  1544. using reference = directory_entry const &;
  1545. using iterator_category = std::input_iterator_tag;
  1546. public:
  1547. // constructors and destructor
  1548. _LIBCPP_INLINE_VISIBILITY
  1549. recursive_directory_iterator() _NOEXCEPT
  1550. : __rec_(false)
  1551. {}
  1552. _LIBCPP_INLINE_VISIBILITY
  1553. explicit recursive_directory_iterator(const path& __p,
  1554. directory_options __xoptions = directory_options::none)
  1555. : recursive_directory_iterator(__p, __xoptions, nullptr)
  1556. { }
  1557. _LIBCPP_INLINE_VISIBILITY
  1558. recursive_directory_iterator(const path& __p,
  1559. directory_options __xoptions, error_code& __ec) _NOEXCEPT
  1560. : recursive_directory_iterator(__p, __xoptions, &__ec)
  1561. { }
  1562. _LIBCPP_INLINE_VISIBILITY
  1563. recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
  1564. : recursive_directory_iterator(__p, directory_options::none, &__ec)
  1565. { }
  1566. recursive_directory_iterator(const recursive_directory_iterator&) = default;
  1567. recursive_directory_iterator(recursive_directory_iterator&&) = default;
  1568. recursive_directory_iterator &
  1569. operator=(const recursive_directory_iterator&) = default;
  1570. _LIBCPP_INLINE_VISIBILITY
  1571. recursive_directory_iterator &
  1572. operator=(recursive_directory_iterator&& __o) noexcept {
  1573. // non-default implementation provided to support self-move assign.
  1574. if (this != &__o) {
  1575. __imp_ = _VSTD::move(__o.__imp_);
  1576. __rec_ = __o.__rec_;
  1577. }
  1578. return *this;
  1579. }
  1580. ~recursive_directory_iterator() = default;
  1581. _LIBCPP_INLINE_VISIBILITY
  1582. const directory_entry& operator*() const
  1583. { return __deref(); }
  1584. _LIBCPP_INLINE_VISIBILITY
  1585. const directory_entry* operator->() const
  1586. { return &__deref(); }
  1587. recursive_directory_iterator& operator++()
  1588. { return __increment(); }
  1589. _LIBCPP_INLINE_VISIBILITY
  1590. __dir_element_proxy operator++(int) {
  1591. __dir_element_proxy __p(**this);
  1592. __increment();
  1593. return __p;
  1594. }
  1595. _LIBCPP_INLINE_VISIBILITY
  1596. recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT
  1597. { return __increment(&__ec); }
  1598. _LIBCPP_FUNC_VIS directory_options options() const;
  1599. _LIBCPP_FUNC_VIS int depth() const;
  1600. _LIBCPP_INLINE_VISIBILITY
  1601. void pop() { __pop(); }
  1602. _LIBCPP_INLINE_VISIBILITY
  1603. void pop(error_code& __ec)
  1604. { __pop(&__ec); }
  1605. _LIBCPP_INLINE_VISIBILITY
  1606. bool recursion_pending() const
  1607. { return __rec_; }
  1608. _LIBCPP_INLINE_VISIBILITY
  1609. void disable_recursion_pending()
  1610. { __rec_ = false; }
  1611. private:
  1612. recursive_directory_iterator(const path& __p, directory_options __opt,
  1613. error_code *__ec);
  1614. _LIBCPP_FUNC_VIS
  1615. const directory_entry& __deref() const;
  1616. _LIBCPP_FUNC_VIS
  1617. bool __try_recursion(error_code* __ec);
  1618. _LIBCPP_FUNC_VIS
  1619. void __advance(error_code* __ec=nullptr);
  1620. _LIBCPP_FUNC_VIS
  1621. recursive_directory_iterator& __increment(error_code *__ec=nullptr);
  1622. _LIBCPP_FUNC_VIS
  1623. void __pop(error_code* __ec=nullptr);
  1624. friend bool operator==(const recursive_directory_iterator&,
  1625. const recursive_directory_iterator&) _NOEXCEPT;
  1626. struct __shared_imp;
  1627. shared_ptr<__shared_imp> __imp_;
  1628. bool __rec_;
  1629. }; // class recursive_directory_iterator
  1630. _LIBCPP_INLINE_VISIBILITY
  1631. inline bool operator==(const recursive_directory_iterator& __lhs,
  1632. const recursive_directory_iterator& __rhs) _NOEXCEPT
  1633. {
  1634. return __lhs.__imp_ == __rhs.__imp_;
  1635. }
  1636. _LIBCPP_INLINE_VISIBILITY
  1637. inline bool operator!=(const recursive_directory_iterator& __lhs,
  1638. const recursive_directory_iterator& __rhs) _NOEXCEPT
  1639. {
  1640. return !(__lhs == __rhs);
  1641. }
  1642. // enable recursive_directory_iterator range-based for statements
  1643. inline _LIBCPP_INLINE_VISIBILITY
  1644. recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
  1645. return __iter;
  1646. }
  1647. inline _LIBCPP_INLINE_VISIBILITY
  1648. recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
  1649. return recursive_directory_iterator();
  1650. }
  1651. _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
  1652. #endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM