fstream 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_FSTREAM
  10. #define _LIBCPP_FSTREAM
  11. /*
  12. fstream synopsis
  13. template <class charT, class traits = char_traits<charT> >
  14. class basic_filebuf
  15. : public basic_streambuf<charT, traits>
  16. {
  17. public:
  18. typedef charT char_type;
  19. typedef traits traits_type;
  20. typedef typename traits_type::int_type int_type;
  21. typedef typename traits_type::pos_type pos_type;
  22. typedef typename traits_type::off_type off_type;
  23. // 27.9.1.2 Constructors/destructor:
  24. basic_filebuf();
  25. basic_filebuf(basic_filebuf&& rhs);
  26. virtual ~basic_filebuf();
  27. // 27.9.1.3 Assign/swap:
  28. basic_filebuf& operator=(basic_filebuf&& rhs);
  29. void swap(basic_filebuf& rhs);
  30. // 27.9.1.4 Members:
  31. bool is_open() const;
  32. basic_filebuf* open(const char* s, ios_base::openmode mode);
  33. basic_filebuf* open(const string& s, ios_base::openmode mode);
  34. basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
  35. basic_filebuf* close();
  36. protected:
  37. // 27.9.1.5 Overridden virtual functions:
  38. virtual streamsize showmanyc();
  39. virtual int_type underflow();
  40. virtual int_type uflow();
  41. virtual int_type pbackfail(int_type c = traits_type::eof());
  42. virtual int_type overflow (int_type c = traits_type::eof());
  43. virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
  44. virtual pos_type seekoff(off_type off, ios_base::seekdir way,
  45. ios_base::openmode which = ios_base::in | ios_base::out);
  46. virtual pos_type seekpos(pos_type sp,
  47. ios_base::openmode which = ios_base::in | ios_base::out);
  48. virtual int sync();
  49. virtual void imbue(const locale& loc);
  50. };
  51. template <class charT, class traits>
  52. void
  53. swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
  54. typedef basic_filebuf<char> filebuf;
  55. typedef basic_filebuf<wchar_t> wfilebuf;
  56. template <class charT, class traits = char_traits<charT> >
  57. class basic_ifstream
  58. : public basic_istream<charT,traits>
  59. {
  60. public:
  61. typedef charT char_type;
  62. typedef traits traits_type;
  63. typedef typename traits_type::int_type int_type;
  64. typedef typename traits_type::pos_type pos_type;
  65. typedef typename traits_type::off_type off_type;
  66. using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
  67. basic_ifstream();
  68. explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
  69. explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
  70. explicit basic_ifstream(const filesystem::path& p,
  71. ios_base::openmode mode = ios_base::in); // C++17
  72. basic_ifstream(basic_ifstream&& rhs);
  73. basic_ifstream& operator=(basic_ifstream&& rhs);
  74. void swap(basic_ifstream& rhs);
  75. basic_filebuf<char_type, traits_type>* rdbuf() const;
  76. native_handle_type native_handle() const noexcept; // Since C++26
  77. bool is_open() const;
  78. void open(const char* s, ios_base::openmode mode = ios_base::in);
  79. void open(const string& s, ios_base::openmode mode = ios_base::in);
  80. void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
  81. void close();
  82. };
  83. template <class charT, class traits>
  84. void
  85. swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
  86. typedef basic_ifstream<char> ifstream;
  87. typedef basic_ifstream<wchar_t> wifstream;
  88. template <class charT, class traits = char_traits<charT> >
  89. class basic_ofstream
  90. : public basic_ostream<charT,traits>
  91. {
  92. public:
  93. typedef charT char_type;
  94. typedef traits traits_type;
  95. typedef typename traits_type::int_type int_type;
  96. typedef typename traits_type::pos_type pos_type;
  97. typedef typename traits_type::off_type off_type;
  98. using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
  99. basic_ofstream();
  100. explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
  101. explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
  102. explicit basic_ofstream(const filesystem::path& p,
  103. ios_base::openmode mode = ios_base::out); // C++17
  104. basic_ofstream(basic_ofstream&& rhs);
  105. basic_ofstream& operator=(basic_ofstream&& rhs);
  106. void swap(basic_ofstream& rhs);
  107. basic_filebuf<char_type, traits_type>* rdbuf() const;
  108. native_handle_type native_handle() const noexcept; // Since C++26
  109. bool is_open() const;
  110. void open(const char* s, ios_base::openmode mode = ios_base::out);
  111. void open(const string& s, ios_base::openmode mode = ios_base::out);
  112. void open(const filesystem::path& p,
  113. ios_base::openmode mode = ios_base::out); // C++17
  114. void close();
  115. };
  116. template <class charT, class traits>
  117. void
  118. swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
  119. typedef basic_ofstream<char> ofstream;
  120. typedef basic_ofstream<wchar_t> wofstream;
  121. template <class charT, class traits=char_traits<charT> >
  122. class basic_fstream
  123. : public basic_iostream<charT,traits>
  124. {
  125. public:
  126. typedef charT char_type;
  127. typedef traits traits_type;
  128. typedef typename traits_type::int_type int_type;
  129. typedef typename traits_type::pos_type pos_type;
  130. typedef typename traits_type::off_type off_type;
  131. using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
  132. basic_fstream();
  133. explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
  134. explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
  135. explicit basic_fstream(const filesystem::path& p,
  136. ios_base::openmode mode = ios_base::in|ios_base::out); C++17
  137. basic_fstream(basic_fstream&& rhs);
  138. basic_fstream& operator=(basic_fstream&& rhs);
  139. void swap(basic_fstream& rhs);
  140. basic_filebuf<char_type, traits_type>* rdbuf() const;
  141. native_handle_type native_handle() const noexcept; // Since C++26
  142. bool is_open() const;
  143. void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
  144. void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
  145. void open(const filesystem::path& s,
  146. ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
  147. void close();
  148. };
  149. template <class charT, class traits>
  150. void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
  151. typedef basic_fstream<char> fstream;
  152. typedef basic_fstream<wchar_t> wfstream;
  153. } // std
  154. */
  155. #include <__algorithm/max.h>
  156. #include <__assert>
  157. #include <__availability>
  158. #include <__config>
  159. #include <__fwd/fstream.h>
  160. #include <__locale>
  161. #include <__utility/move.h>
  162. #include <__utility/swap.h>
  163. #include <__utility/unreachable.h>
  164. #include <cstdio>
  165. #include <filesystem>
  166. #include <istream>
  167. #include <ostream>
  168. #include <typeinfo>
  169. #include <version>
  170. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  171. # pragma GCC system_header
  172. #endif
  173. _LIBCPP_PUSH_MACROS
  174. #include <__undef_macros>
  175. #if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
  176. # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
  177. #endif
  178. #if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
  179. _LIBCPP_BEGIN_NAMESPACE_STD
  180. # if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
  181. _LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
  182. # endif
  183. template <class _CharT, class _Traits>
  184. class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
  185. public:
  186. typedef _CharT char_type;
  187. typedef _Traits traits_type;
  188. typedef typename traits_type::int_type int_type;
  189. typedef typename traits_type::pos_type pos_type;
  190. typedef typename traits_type::off_type off_type;
  191. typedef typename traits_type::state_type state_type;
  192. # if _LIBCPP_STD_VER >= 26
  193. # if defined(_LIBCPP_WIN32API)
  194. using native_handle_type = void*; // HANDLE
  195. # elif __has_include(<unistd.h>)
  196. using native_handle_type = int; // POSIX file descriptor
  197. # else
  198. # error "Provide a native file handle!"
  199. # endif
  200. # endif
  201. // 27.9.1.2 Constructors/destructor:
  202. basic_filebuf();
  203. basic_filebuf(basic_filebuf&& __rhs);
  204. ~basic_filebuf() override;
  205. // 27.9.1.3 Assign/swap:
  206. _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
  207. void swap(basic_filebuf& __rhs);
  208. // 27.9.1.4 Members:
  209. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  210. basic_filebuf* open(const char* __s, ios_base::openmode __mode);
  211. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  212. basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
  213. # endif
  214. _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
  215. # if _LIBCPP_STD_VER >= 17
  216. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
  217. open(const filesystem::path& __p, ios_base::openmode __mode) {
  218. return open(__p.c_str(), __mode);
  219. }
  220. # endif
  221. _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
  222. basic_filebuf* close();
  223. # if _LIBCPP_STD_VER >= 26
  224. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
  225. _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
  226. # if defined(_LIBCPP_WIN32API)
  227. return std::__filebuf_windows_native_handle(__file_);
  228. # elif __has_include(<unistd.h>)
  229. return fileno(__file_);
  230. # else
  231. # error "Provide a way to determine the file native handle!"
  232. # endif
  233. }
  234. # endif // _LIBCPP_STD_VER >= 26
  235. _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
  236. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  237. _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
  238. # endif
  239. protected:
  240. // 27.9.1.5 Overridden virtual functions:
  241. int_type underflow() override;
  242. int_type pbackfail(int_type __c = traits_type::eof()) override;
  243. int_type overflow(int_type __c = traits_type::eof()) override;
  244. basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
  245. pos_type
  246. seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
  247. pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
  248. int sync() override;
  249. void imbue(const locale& __loc) override;
  250. private:
  251. char* __extbuf_;
  252. const char* __extbufnext_;
  253. const char* __extbufend_;
  254. char __extbuf_min_[8];
  255. size_t __ebs_;
  256. char_type* __intbuf_;
  257. size_t __ibs_;
  258. FILE* __file_;
  259. const codecvt<char_type, char, state_type>* __cv_;
  260. state_type __st_;
  261. state_type __st_last_;
  262. ios_base::openmode __om_;
  263. ios_base::openmode __cm_;
  264. bool __owns_eb_;
  265. bool __owns_ib_;
  266. bool __always_noconv_;
  267. bool __read_mode();
  268. void __write_mode();
  269. _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
  270. // There are multiple (__)open function, they use different C-API open
  271. // function. After that call these functions behave the same. This function
  272. // does that part and determines the final return value.
  273. _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
  274. __file_ = __file;
  275. if (!__file_)
  276. return nullptr;
  277. __om_ = __mode;
  278. if (__mode & ios_base::ate) {
  279. if (fseek(__file_, 0, SEEK_END)) {
  280. fclose(__file_);
  281. __file_ = nullptr;
  282. return nullptr;
  283. }
  284. }
  285. return this;
  286. }
  287. };
  288. template <class _CharT, class _Traits>
  289. basic_filebuf<_CharT, _Traits>::basic_filebuf()
  290. : __extbuf_(nullptr),
  291. __extbufnext_(nullptr),
  292. __extbufend_(nullptr),
  293. __ebs_(0),
  294. __intbuf_(nullptr),
  295. __ibs_(0),
  296. __file_(nullptr),
  297. __cv_(nullptr),
  298. __st_(),
  299. __st_last_(),
  300. __om_(0),
  301. __cm_(0),
  302. __owns_eb_(false),
  303. __owns_ib_(false),
  304. __always_noconv_(false) {
  305. if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
  306. __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
  307. __always_noconv_ = __cv_->always_noconv();
  308. }
  309. setbuf(nullptr, 4096);
  310. }
  311. template <class _CharT, class _Traits>
  312. basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
  313. if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
  314. __extbuf_ = __extbuf_min_;
  315. __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
  316. __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
  317. } else {
  318. __extbuf_ = __rhs.__extbuf_;
  319. __extbufnext_ = __rhs.__extbufnext_;
  320. __extbufend_ = __rhs.__extbufend_;
  321. }
  322. __ebs_ = __rhs.__ebs_;
  323. __intbuf_ = __rhs.__intbuf_;
  324. __ibs_ = __rhs.__ibs_;
  325. __file_ = __rhs.__file_;
  326. __cv_ = __rhs.__cv_;
  327. __st_ = __rhs.__st_;
  328. __st_last_ = __rhs.__st_last_;
  329. __om_ = __rhs.__om_;
  330. __cm_ = __rhs.__cm_;
  331. __owns_eb_ = __rhs.__owns_eb_;
  332. __owns_ib_ = __rhs.__owns_ib_;
  333. __always_noconv_ = __rhs.__always_noconv_;
  334. if (__rhs.pbase()) {
  335. if (__rhs.pbase() == __rhs.__intbuf_)
  336. this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
  337. else
  338. this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
  339. this->__pbump(__rhs.pptr() - __rhs.pbase());
  340. } else if (__rhs.eback()) {
  341. if (__rhs.eback() == __rhs.__intbuf_)
  342. this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
  343. else
  344. this->setg((char_type*)__extbuf_,
  345. (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
  346. (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
  347. }
  348. __rhs.__extbuf_ = nullptr;
  349. __rhs.__extbufnext_ = nullptr;
  350. __rhs.__extbufend_ = nullptr;
  351. __rhs.__ebs_ = 0;
  352. __rhs.__intbuf_ = 0;
  353. __rhs.__ibs_ = 0;
  354. __rhs.__file_ = nullptr;
  355. __rhs.__st_ = state_type();
  356. __rhs.__st_last_ = state_type();
  357. __rhs.__om_ = 0;
  358. __rhs.__cm_ = 0;
  359. __rhs.__owns_eb_ = false;
  360. __rhs.__owns_ib_ = false;
  361. __rhs.setg(0, 0, 0);
  362. __rhs.setp(0, 0);
  363. }
  364. template <class _CharT, class _Traits>
  365. inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
  366. close();
  367. swap(__rhs);
  368. return *this;
  369. }
  370. template <class _CharT, class _Traits>
  371. basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
  372. # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  373. try {
  374. # endif // _LIBCPP_HAS_NO_EXCEPTIONS
  375. close();
  376. # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  377. } catch (...) {
  378. }
  379. # endif // _LIBCPP_HAS_NO_EXCEPTIONS
  380. if (__owns_eb_)
  381. delete[] __extbuf_;
  382. if (__owns_ib_)
  383. delete[] __intbuf_;
  384. }
  385. template <class _CharT, class _Traits>
  386. void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
  387. basic_streambuf<char_type, traits_type>::swap(__rhs);
  388. if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
  389. // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
  390. std::swap(__extbuf_, __rhs.__extbuf_);
  391. std::swap(__extbufnext_, __rhs.__extbufnext_);
  392. std::swap(__extbufend_, __rhs.__extbufend_);
  393. } else {
  394. ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
  395. ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
  396. ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
  397. ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
  398. if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
  399. // *this uses the small buffer, but __rhs doesn't.
  400. __extbuf_ = __rhs.__extbuf_;
  401. __rhs.__extbuf_ = __rhs.__extbuf_min_;
  402. std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
  403. } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
  404. // *this doesn't use the small buffer, but __rhs does.
  405. __rhs.__extbuf_ = __extbuf_;
  406. __extbuf_ = __extbuf_min_;
  407. std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
  408. } else {
  409. // Both *this and __rhs use the small buffer.
  410. char __tmp[sizeof(__extbuf_min_)];
  411. std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
  412. std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
  413. std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
  414. }
  415. __extbufnext_ = __extbuf_ + __rn;
  416. __extbufend_ = __extbuf_ + __re;
  417. __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
  418. __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
  419. }
  420. std::swap(__ebs_, __rhs.__ebs_);
  421. std::swap(__intbuf_, __rhs.__intbuf_);
  422. std::swap(__ibs_, __rhs.__ibs_);
  423. std::swap(__file_, __rhs.__file_);
  424. std::swap(__cv_, __rhs.__cv_);
  425. std::swap(__st_, __rhs.__st_);
  426. std::swap(__st_last_, __rhs.__st_last_);
  427. std::swap(__om_, __rhs.__om_);
  428. std::swap(__cm_, __rhs.__cm_);
  429. std::swap(__owns_eb_, __rhs.__owns_eb_);
  430. std::swap(__owns_ib_, __rhs.__owns_ib_);
  431. std::swap(__always_noconv_, __rhs.__always_noconv_);
  432. if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
  433. ptrdiff_t __n = this->gptr() - this->eback();
  434. ptrdiff_t __e = this->egptr() - this->eback();
  435. this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
  436. } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
  437. ptrdiff_t __n = this->pptr() - this->pbase();
  438. ptrdiff_t __e = this->epptr() - this->pbase();
  439. this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
  440. this->__pbump(__n);
  441. }
  442. if (__rhs.eback() == (char_type*)__extbuf_min_) {
  443. ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
  444. ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
  445. __rhs.setg(
  446. (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
  447. } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
  448. ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
  449. ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
  450. __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
  451. __rhs.__pbump(__n);
  452. }
  453. }
  454. template <class _CharT, class _Traits>
  455. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
  456. __x.swap(__y);
  457. }
  458. template <class _CharT, class _Traits>
  459. inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
  460. return __file_ != nullptr;
  461. }
  462. template <class _CharT, class _Traits>
  463. const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
  464. switch (__mode & ~ios_base::ate) {
  465. case ios_base::out:
  466. case ios_base::out | ios_base::trunc:
  467. return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
  468. case ios_base::out | ios_base::app:
  469. case ios_base::app:
  470. return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
  471. case ios_base::in:
  472. return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
  473. case ios_base::in | ios_base::out:
  474. return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  475. case ios_base::in | ios_base::out | ios_base::trunc:
  476. return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  477. case ios_base::in | ios_base::out | ios_base::app:
  478. case ios_base::in | ios_base::app:
  479. return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  480. case ios_base::out | ios_base::binary:
  481. case ios_base::out | ios_base::trunc | ios_base::binary:
  482. return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  483. case ios_base::out | ios_base::app | ios_base::binary:
  484. case ios_base::app | ios_base::binary:
  485. return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
  486. case ios_base::in | ios_base::binary:
  487. return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  488. case ios_base::in | ios_base::out | ios_base::binary:
  489. return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  490. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
  491. return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  492. case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  493. case ios_base::in | ios_base::app | ios_base::binary:
  494. return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  495. # if _LIBCPP_STD_VER >= 23
  496. case ios_base::out | ios_base::noreplace:
  497. case ios_base::out | ios_base::trunc | ios_base::noreplace:
  498. return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  499. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
  500. return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
  501. case ios_base::out | ios_base::binary | ios_base::noreplace:
  502. case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  503. return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  504. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  505. return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  506. # endif // _LIBCPP_STD_VER >= 23
  507. default:
  508. return nullptr;
  509. }
  510. __libcpp_unreachable();
  511. }
  512. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  513. template <class _CharT, class _Traits>
  514. const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
  515. switch (__mode & ~ios_base::ate) {
  516. case ios_base::out:
  517. case ios_base::out | ios_base::trunc:
  518. return L"w";
  519. case ios_base::out | ios_base::app:
  520. case ios_base::app:
  521. return L"a";
  522. case ios_base::in:
  523. return L"r";
  524. case ios_base::in | ios_base::out:
  525. return L"r+";
  526. case ios_base::in | ios_base::out | ios_base::trunc:
  527. return L"w+";
  528. case ios_base::in | ios_base::out | ios_base::app:
  529. case ios_base::in | ios_base::app:
  530. return L"a+";
  531. case ios_base::out | ios_base::binary:
  532. case ios_base::out | ios_base::trunc | ios_base::binary:
  533. return L"wb";
  534. case ios_base::out | ios_base::app | ios_base::binary:
  535. case ios_base::app | ios_base::binary:
  536. return L"ab";
  537. case ios_base::in | ios_base::binary:
  538. return L"rb";
  539. case ios_base::in | ios_base::out | ios_base::binary:
  540. return L"r+b";
  541. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
  542. return L"w+b";
  543. case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  544. case ios_base::in | ios_base::app | ios_base::binary:
  545. return L"a+b";
  546. # if _LIBCPP_STD_VER >= 23
  547. case ios_base::out | ios_base::noreplace:
  548. case ios_base::out | ios_base::trunc | ios_base::noreplace:
  549. return L"wx";
  550. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
  551. return L"w+x";
  552. case ios_base::out | ios_base::binary | ios_base::noreplace:
  553. case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  554. return L"wbx";
  555. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  556. return L"w+bx";
  557. # endif // _LIBCPP_STD_VER >= 23
  558. default:
  559. return nullptr;
  560. }
  561. __libcpp_unreachable();
  562. }
  563. # endif
  564. template <class _CharT, class _Traits>
  565. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  566. if (__file_)
  567. return nullptr;
  568. const char* __mdstr = __make_mdstring(__mode);
  569. if (!__mdstr)
  570. return nullptr;
  571. return __do_open(fopen(__s, __mdstr), __mode);
  572. }
  573. template <class _CharT, class _Traits>
  574. inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  575. if (__file_)
  576. return nullptr;
  577. const char* __mdstr = __make_mdstring(__mode);
  578. if (!__mdstr)
  579. return nullptr;
  580. return __do_open(fdopen(__fd, __mdstr), __mode);
  581. }
  582. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  583. // This is basically the same as the char* overload except that it uses _wfopen
  584. // and long mode strings.
  585. template <class _CharT, class _Traits>
  586. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  587. if (__file_)
  588. return nullptr;
  589. const wchar_t* __mdstr = __make_mdwstring(__mode);
  590. if (!__mdstr)
  591. return nullptr;
  592. return __do_open(_wfopen(__s, __mdstr), __mode);
  593. }
  594. # endif
  595. template <class _CharT, class _Traits>
  596. inline basic_filebuf<_CharT, _Traits>*
  597. basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  598. return open(__s.c_str(), __mode);
  599. }
  600. template <class _CharT, class _Traits>
  601. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
  602. basic_filebuf<_CharT, _Traits>* __rt = nullptr;
  603. if (__file_) {
  604. __rt = this;
  605. unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
  606. if (sync())
  607. __rt = nullptr;
  608. if (fclose(__h.release()))
  609. __rt = nullptr;
  610. __file_ = nullptr;
  611. setbuf(0, 0);
  612. }
  613. return __rt;
  614. }
  615. template <class _CharT, class _Traits>
  616. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
  617. if (__file_ == nullptr)
  618. return traits_type::eof();
  619. bool __initial = __read_mode();
  620. char_type __1buf;
  621. if (this->gptr() == nullptr)
  622. this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
  623. const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
  624. int_type __c = traits_type::eof();
  625. if (this->gptr() == this->egptr()) {
  626. std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
  627. if (__always_noconv_) {
  628. size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
  629. __nmemb = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
  630. if (__nmemb != 0) {
  631. this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
  632. __c = traits_type::to_int_type(*this->gptr());
  633. }
  634. } else {
  635. if (__extbufend_ != __extbufnext_) {
  636. _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
  637. _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
  638. std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
  639. }
  640. __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
  641. __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
  642. size_t __nmemb =
  643. std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
  644. codecvt_base::result __r;
  645. __st_last_ = __st_;
  646. size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
  647. if (__nr != 0) {
  648. if (!__cv_)
  649. __throw_bad_cast();
  650. __extbufend_ = __extbufnext_ + __nr;
  651. char_type* __inext;
  652. __r = __cv_->in(
  653. __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
  654. if (__r == codecvt_base::noconv) {
  655. this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
  656. __c = traits_type::to_int_type(*this->gptr());
  657. } else if (__inext != this->eback() + __unget_sz) {
  658. this->setg(this->eback(), this->eback() + __unget_sz, __inext);
  659. __c = traits_type::to_int_type(*this->gptr());
  660. }
  661. }
  662. }
  663. } else
  664. __c = traits_type::to_int_type(*this->gptr());
  665. if (this->eback() == &__1buf)
  666. this->setg(nullptr, nullptr, nullptr);
  667. return __c;
  668. }
  669. template <class _CharT, class _Traits>
  670. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
  671. if (__file_ && this->eback() < this->gptr()) {
  672. if (traits_type::eq_int_type(__c, traits_type::eof())) {
  673. this->gbump(-1);
  674. return traits_type::not_eof(__c);
  675. }
  676. if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
  677. this->gbump(-1);
  678. *this->gptr() = traits_type::to_char_type(__c);
  679. return __c;
  680. }
  681. }
  682. return traits_type::eof();
  683. }
  684. template <class _CharT, class _Traits>
  685. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
  686. if (__file_ == nullptr)
  687. return traits_type::eof();
  688. __write_mode();
  689. char_type __1buf;
  690. char_type* __pb_save = this->pbase();
  691. char_type* __epb_save = this->epptr();
  692. if (!traits_type::eq_int_type(__c, traits_type::eof())) {
  693. if (this->pptr() == nullptr)
  694. this->setp(&__1buf, &__1buf + 1);
  695. *this->pptr() = traits_type::to_char_type(__c);
  696. this->pbump(1);
  697. }
  698. if (this->pptr() != this->pbase()) {
  699. if (__always_noconv_) {
  700. size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
  701. if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
  702. return traits_type::eof();
  703. } else {
  704. char* __extbe = __extbuf_;
  705. codecvt_base::result __r;
  706. do {
  707. if (!__cv_)
  708. __throw_bad_cast();
  709. const char_type* __e;
  710. __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
  711. if (__e == this->pbase())
  712. return traits_type::eof();
  713. if (__r == codecvt_base::noconv) {
  714. size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
  715. if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
  716. return traits_type::eof();
  717. } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
  718. size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
  719. if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
  720. return traits_type::eof();
  721. if (__r == codecvt_base::partial) {
  722. this->setp(const_cast<char_type*>(__e), this->pptr());
  723. this->__pbump(this->epptr() - this->pbase());
  724. }
  725. } else
  726. return traits_type::eof();
  727. } while (__r == codecvt_base::partial);
  728. }
  729. this->setp(__pb_save, __epb_save);
  730. }
  731. return traits_type::not_eof(__c);
  732. }
  733. template <class _CharT, class _Traits>
  734. basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
  735. this->setg(nullptr, nullptr, nullptr);
  736. this->setp(nullptr, nullptr);
  737. if (__owns_eb_)
  738. delete[] __extbuf_;
  739. if (__owns_ib_)
  740. delete[] __intbuf_;
  741. __ebs_ = __n;
  742. if (__ebs_ > sizeof(__extbuf_min_)) {
  743. if (__always_noconv_ && __s) {
  744. __extbuf_ = (char*)__s;
  745. __owns_eb_ = false;
  746. } else {
  747. __extbuf_ = new char[__ebs_];
  748. __owns_eb_ = true;
  749. }
  750. } else {
  751. __extbuf_ = __extbuf_min_;
  752. __ebs_ = sizeof(__extbuf_min_);
  753. __owns_eb_ = false;
  754. }
  755. if (!__always_noconv_) {
  756. __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
  757. if (__s && __ibs_ > sizeof(__extbuf_min_)) {
  758. __intbuf_ = __s;
  759. __owns_ib_ = false;
  760. } else {
  761. __intbuf_ = new char_type[__ibs_];
  762. __owns_ib_ = true;
  763. }
  764. } else {
  765. __ibs_ = 0;
  766. __intbuf_ = nullptr;
  767. __owns_ib_ = false;
  768. }
  769. return this;
  770. }
  771. template <class _CharT, class _Traits>
  772. typename basic_filebuf<_CharT, _Traits>::pos_type
  773. basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
  774. if (!__cv_)
  775. __throw_bad_cast();
  776. int __width = __cv_->encoding();
  777. if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
  778. return pos_type(off_type(-1));
  779. // __width > 0 || __off == 0
  780. int __whence;
  781. switch (__way) {
  782. case ios_base::beg:
  783. __whence = SEEK_SET;
  784. break;
  785. case ios_base::cur:
  786. __whence = SEEK_CUR;
  787. break;
  788. case ios_base::end:
  789. __whence = SEEK_END;
  790. break;
  791. default:
  792. return pos_type(off_type(-1));
  793. }
  794. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  795. if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
  796. return pos_type(off_type(-1));
  797. pos_type __r = ftell(__file_);
  798. # else
  799. if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
  800. return pos_type(off_type(-1));
  801. pos_type __r = ftello(__file_);
  802. # endif
  803. __r.state(__st_);
  804. return __r;
  805. }
  806. template <class _CharT, class _Traits>
  807. typename basic_filebuf<_CharT, _Traits>::pos_type
  808. basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
  809. if (__file_ == nullptr || sync())
  810. return pos_type(off_type(-1));
  811. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  812. if (fseek(__file_, __sp, SEEK_SET))
  813. return pos_type(off_type(-1));
  814. # else
  815. if (::fseeko(__file_, __sp, SEEK_SET))
  816. return pos_type(off_type(-1));
  817. # endif
  818. __st_ = __sp.state();
  819. return __sp;
  820. }
  821. template <class _CharT, class _Traits>
  822. int basic_filebuf<_CharT, _Traits>::sync() {
  823. if (__file_ == nullptr)
  824. return 0;
  825. if (!__cv_)
  826. __throw_bad_cast();
  827. if (__cm_ & ios_base::out) {
  828. if (this->pptr() != this->pbase())
  829. if (overflow() == traits_type::eof())
  830. return -1;
  831. codecvt_base::result __r;
  832. do {
  833. char* __extbe;
  834. __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
  835. size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
  836. if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
  837. return -1;
  838. } while (__r == codecvt_base::partial);
  839. if (__r == codecvt_base::error)
  840. return -1;
  841. if (fflush(__file_))
  842. return -1;
  843. } else if (__cm_ & ios_base::in) {
  844. off_type __c;
  845. state_type __state = __st_last_;
  846. bool __update_st = false;
  847. if (__always_noconv_)
  848. __c = this->egptr() - this->gptr();
  849. else {
  850. int __width = __cv_->encoding();
  851. __c = __extbufend_ - __extbufnext_;
  852. if (__width > 0)
  853. __c += __width * (this->egptr() - this->gptr());
  854. else {
  855. if (this->gptr() != this->egptr()) {
  856. const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
  857. __c += __extbufnext_ - __extbuf_ - __off;
  858. __update_st = true;
  859. }
  860. }
  861. }
  862. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  863. if (fseek(__file_, -__c, SEEK_CUR))
  864. return -1;
  865. # else
  866. if (::fseeko(__file_, -__c, SEEK_CUR))
  867. return -1;
  868. # endif
  869. if (__update_st)
  870. __st_ = __state;
  871. __extbufnext_ = __extbufend_ = __extbuf_;
  872. this->setg(nullptr, nullptr, nullptr);
  873. __cm_ = 0;
  874. }
  875. return 0;
  876. }
  877. template <class _CharT, class _Traits>
  878. void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
  879. sync();
  880. __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
  881. bool __old_anc = __always_noconv_;
  882. __always_noconv_ = __cv_->always_noconv();
  883. if (__old_anc != __always_noconv_) {
  884. this->setg(nullptr, nullptr, nullptr);
  885. this->setp(nullptr, nullptr);
  886. // invariant, char_type is char, else we couldn't get here
  887. if (__always_noconv_) // need to dump __intbuf_
  888. {
  889. if (__owns_eb_)
  890. delete[] __extbuf_;
  891. __owns_eb_ = __owns_ib_;
  892. __ebs_ = __ibs_;
  893. __extbuf_ = (char*)__intbuf_;
  894. __ibs_ = 0;
  895. __intbuf_ = nullptr;
  896. __owns_ib_ = false;
  897. } else // need to obtain an __intbuf_.
  898. { // If __extbuf_ is user-supplied, use it, else new __intbuf_
  899. if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
  900. __ibs_ = __ebs_;
  901. __intbuf_ = (char_type*)__extbuf_;
  902. __owns_ib_ = false;
  903. __extbuf_ = new char[__ebs_];
  904. __owns_eb_ = true;
  905. } else {
  906. __ibs_ = __ebs_;
  907. __intbuf_ = new char_type[__ibs_];
  908. __owns_ib_ = true;
  909. }
  910. }
  911. }
  912. }
  913. template <class _CharT, class _Traits>
  914. bool basic_filebuf<_CharT, _Traits>::__read_mode() {
  915. if (!(__cm_ & ios_base::in)) {
  916. this->setp(nullptr, nullptr);
  917. if (__always_noconv_)
  918. this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
  919. else
  920. this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
  921. __cm_ = ios_base::in;
  922. return true;
  923. }
  924. return false;
  925. }
  926. template <class _CharT, class _Traits>
  927. void basic_filebuf<_CharT, _Traits>::__write_mode() {
  928. if (!(__cm_ & ios_base::out)) {
  929. this->setg(nullptr, nullptr, nullptr);
  930. if (__ebs_ > sizeof(__extbuf_min_)) {
  931. if (__always_noconv_)
  932. this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
  933. else
  934. this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
  935. } else
  936. this->setp(nullptr, nullptr);
  937. __cm_ = ios_base::out;
  938. }
  939. }
  940. // basic_ifstream
  941. template <class _CharT, class _Traits>
  942. class _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
  943. public:
  944. typedef _CharT char_type;
  945. typedef _Traits traits_type;
  946. typedef typename traits_type::int_type int_type;
  947. typedef typename traits_type::pos_type pos_type;
  948. typedef typename traits_type::off_type off_type;
  949. # if _LIBCPP_STD_VER >= 26
  950. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  951. # endif
  952. _LIBCPP_HIDE_FROM_ABI basic_ifstream();
  953. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
  954. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  955. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
  956. # endif
  957. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
  958. # if _LIBCPP_STD_VER >= 17
  959. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(
  960. const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
  961. : basic_ifstream(__p.c_str(), __mode) {}
  962. # endif // _LIBCPP_STD_VER >= 17
  963. _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
  964. _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
  965. _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
  966. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  967. # if _LIBCPP_STD_VER >= 26
  968. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  969. # endif
  970. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  971. void open(const char* __s, ios_base::openmode __mode = ios_base::in);
  972. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  973. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
  974. # endif
  975. void open(const string& __s, ios_base::openmode __mode = ios_base::in);
  976. # if _LIBCPP_STD_VER >= 17
  977. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  978. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
  979. return open(__p.c_str(), __mode);
  980. }
  981. # endif // _LIBCPP_STD_VER >= 17
  982. _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  983. _LIBCPP_HIDE_FROM_ABI void close();
  984. private:
  985. basic_filebuf<char_type, traits_type> __sb_;
  986. };
  987. template <class _CharT, class _Traits>
  988. inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
  989. template <class _CharT, class _Traits>
  990. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
  991. : basic_istream<char_type, traits_type>(&__sb_) {
  992. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  993. this->setstate(ios_base::failbit);
  994. }
  995. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  996. template <class _CharT, class _Traits>
  997. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
  998. : basic_istream<char_type, traits_type>(&__sb_) {
  999. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  1000. this->setstate(ios_base::failbit);
  1001. }
  1002. # endif
  1003. template <class _CharT, class _Traits>
  1004. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
  1005. : basic_istream<char_type, traits_type>(&__sb_) {
  1006. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  1007. this->setstate(ios_base::failbit);
  1008. }
  1009. template <class _CharT, class _Traits>
  1010. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
  1011. : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1012. this->set_rdbuf(&__sb_);
  1013. }
  1014. template <class _CharT, class _Traits>
  1015. inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
  1016. basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
  1017. __sb_ = std::move(__rhs.__sb_);
  1018. return *this;
  1019. }
  1020. template <class _CharT, class _Traits>
  1021. inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
  1022. basic_istream<char_type, traits_type>::swap(__rhs);
  1023. __sb_.swap(__rhs.__sb_);
  1024. }
  1025. template <class _CharT, class _Traits>
  1026. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
  1027. __x.swap(__y);
  1028. }
  1029. template <class _CharT, class _Traits>
  1030. inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
  1031. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1032. }
  1033. template <class _CharT, class _Traits>
  1034. inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
  1035. return __sb_.is_open();
  1036. }
  1037. template <class _CharT, class _Traits>
  1038. void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1039. if (__sb_.open(__s, __mode | ios_base::in))
  1040. this->clear();
  1041. else
  1042. this->setstate(ios_base::failbit);
  1043. }
  1044. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1045. template <class _CharT, class _Traits>
  1046. void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1047. if (__sb_.open(__s, __mode | ios_base::in))
  1048. this->clear();
  1049. else
  1050. this->setstate(ios_base::failbit);
  1051. }
  1052. # endif
  1053. template <class _CharT, class _Traits>
  1054. void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1055. if (__sb_.open(__s, __mode | ios_base::in))
  1056. this->clear();
  1057. else
  1058. this->setstate(ios_base::failbit);
  1059. }
  1060. template <class _CharT, class _Traits>
  1061. inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  1062. if (__sb_.__open(__fd, __mode | ios_base::in))
  1063. this->clear();
  1064. else
  1065. this->setstate(ios_base::failbit);
  1066. }
  1067. template <class _CharT, class _Traits>
  1068. inline void basic_ifstream<_CharT, _Traits>::close() {
  1069. if (__sb_.close() == 0)
  1070. this->setstate(ios_base::failbit);
  1071. }
  1072. // basic_ofstream
  1073. template <class _CharT, class _Traits>
  1074. class _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
  1075. public:
  1076. typedef _CharT char_type;
  1077. typedef _Traits traits_type;
  1078. typedef typename traits_type::int_type int_type;
  1079. typedef typename traits_type::pos_type pos_type;
  1080. typedef typename traits_type::off_type off_type;
  1081. # if _LIBCPP_STD_VER >= 26
  1082. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  1083. # endif
  1084. _LIBCPP_HIDE_FROM_ABI basic_ofstream();
  1085. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
  1086. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1087. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
  1088. # endif
  1089. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
  1090. # if _LIBCPP_STD_VER >= 17
  1091. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(
  1092. const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
  1093. : basic_ofstream(__p.c_str(), __mode) {}
  1094. # endif // _LIBCPP_STD_VER >= 17
  1095. _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
  1096. _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
  1097. _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
  1098. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  1099. # if _LIBCPP_STD_VER >= 26
  1100. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  1101. # endif
  1102. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  1103. void open(const char* __s, ios_base::openmode __mode = ios_base::out);
  1104. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1105. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
  1106. # endif
  1107. void open(const string& __s, ios_base::openmode __mode = ios_base::out);
  1108. # if _LIBCPP_STD_VER >= 17
  1109. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  1110. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
  1111. return open(__p.c_str(), __mode);
  1112. }
  1113. # endif // _LIBCPP_STD_VER >= 17
  1114. _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  1115. _LIBCPP_HIDE_FROM_ABI void close();
  1116. private:
  1117. basic_filebuf<char_type, traits_type> __sb_;
  1118. };
  1119. template <class _CharT, class _Traits>
  1120. inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
  1121. template <class _CharT, class _Traits>
  1122. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
  1123. : basic_ostream<char_type, traits_type>(&__sb_) {
  1124. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1125. this->setstate(ios_base::failbit);
  1126. }
  1127. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1128. template <class _CharT, class _Traits>
  1129. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
  1130. : basic_ostream<char_type, traits_type>(&__sb_) {
  1131. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1132. this->setstate(ios_base::failbit);
  1133. }
  1134. # endif
  1135. template <class _CharT, class _Traits>
  1136. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
  1137. : basic_ostream<char_type, traits_type>(&__sb_) {
  1138. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1139. this->setstate(ios_base::failbit);
  1140. }
  1141. template <class _CharT, class _Traits>
  1142. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
  1143. : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1144. this->set_rdbuf(&__sb_);
  1145. }
  1146. template <class _CharT, class _Traits>
  1147. inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
  1148. basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
  1149. __sb_ = std::move(__rhs.__sb_);
  1150. return *this;
  1151. }
  1152. template <class _CharT, class _Traits>
  1153. inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
  1154. basic_ostream<char_type, traits_type>::swap(__rhs);
  1155. __sb_.swap(__rhs.__sb_);
  1156. }
  1157. template <class _CharT, class _Traits>
  1158. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
  1159. __x.swap(__y);
  1160. }
  1161. template <class _CharT, class _Traits>
  1162. inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
  1163. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1164. }
  1165. template <class _CharT, class _Traits>
  1166. inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
  1167. return __sb_.is_open();
  1168. }
  1169. template <class _CharT, class _Traits>
  1170. void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1171. if (__sb_.open(__s, __mode | ios_base::out))
  1172. this->clear();
  1173. else
  1174. this->setstate(ios_base::failbit);
  1175. }
  1176. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1177. template <class _CharT, class _Traits>
  1178. void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1179. if (__sb_.open(__s, __mode | ios_base::out))
  1180. this->clear();
  1181. else
  1182. this->setstate(ios_base::failbit);
  1183. }
  1184. # endif
  1185. template <class _CharT, class _Traits>
  1186. void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1187. if (__sb_.open(__s, __mode | ios_base::out))
  1188. this->clear();
  1189. else
  1190. this->setstate(ios_base::failbit);
  1191. }
  1192. template <class _CharT, class _Traits>
  1193. inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  1194. if (__sb_.__open(__fd, __mode | ios_base::out))
  1195. this->clear();
  1196. else
  1197. this->setstate(ios_base::failbit);
  1198. }
  1199. template <class _CharT, class _Traits>
  1200. inline void basic_ofstream<_CharT, _Traits>::close() {
  1201. if (__sb_.close() == nullptr)
  1202. this->setstate(ios_base::failbit);
  1203. }
  1204. // basic_fstream
  1205. template <class _CharT, class _Traits>
  1206. class _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
  1207. public:
  1208. typedef _CharT char_type;
  1209. typedef _Traits traits_type;
  1210. typedef typename traits_type::int_type int_type;
  1211. typedef typename traits_type::pos_type pos_type;
  1212. typedef typename traits_type::off_type off_type;
  1213. # if _LIBCPP_STD_VER >= 26
  1214. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  1215. # endif
  1216. _LIBCPP_HIDE_FROM_ABI basic_fstream();
  1217. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
  1218. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1219. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1220. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
  1221. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1222. # endif
  1223. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
  1224. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1225. # if _LIBCPP_STD_VER >= 17
  1226. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
  1227. const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
  1228. : basic_fstream(__p.c_str(), __mode) {}
  1229. # endif // _LIBCPP_STD_VER >= 17
  1230. _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
  1231. _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
  1232. _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
  1233. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  1234. # if _LIBCPP_STD_VER >= 26
  1235. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  1236. # endif
  1237. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  1238. _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1239. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1240. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1241. # endif
  1242. _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1243. # if _LIBCPP_STD_VER >= 17
  1244. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  1245. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
  1246. return open(__p.c_str(), __mode);
  1247. }
  1248. # endif // _LIBCPP_STD_VER >= 17
  1249. _LIBCPP_HIDE_FROM_ABI void close();
  1250. private:
  1251. basic_filebuf<char_type, traits_type> __sb_;
  1252. };
  1253. template <class _CharT, class _Traits>
  1254. inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
  1255. template <class _CharT, class _Traits>
  1256. inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
  1257. : basic_iostream<char_type, traits_type>(&__sb_) {
  1258. if (__sb_.open(__s, __mode) == nullptr)
  1259. this->setstate(ios_base::failbit);
  1260. }
  1261. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1262. template <class _CharT, class _Traits>
  1263. inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
  1264. : basic_iostream<char_type, traits_type>(&__sb_) {
  1265. if (__sb_.open(__s, __mode) == nullptr)
  1266. this->setstate(ios_base::failbit);
  1267. }
  1268. # endif
  1269. template <class _CharT, class _Traits>
  1270. inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
  1271. : basic_iostream<char_type, traits_type>(&__sb_) {
  1272. if (__sb_.open(__s, __mode) == nullptr)
  1273. this->setstate(ios_base::failbit);
  1274. }
  1275. template <class _CharT, class _Traits>
  1276. inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
  1277. : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1278. this->set_rdbuf(&__sb_);
  1279. }
  1280. template <class _CharT, class _Traits>
  1281. inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
  1282. basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
  1283. __sb_ = std::move(__rhs.__sb_);
  1284. return *this;
  1285. }
  1286. template <class _CharT, class _Traits>
  1287. inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
  1288. basic_iostream<char_type, traits_type>::swap(__rhs);
  1289. __sb_.swap(__rhs.__sb_);
  1290. }
  1291. template <class _CharT, class _Traits>
  1292. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
  1293. __x.swap(__y);
  1294. }
  1295. template <class _CharT, class _Traits>
  1296. inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
  1297. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1298. }
  1299. template <class _CharT, class _Traits>
  1300. inline bool basic_fstream<_CharT, _Traits>::is_open() const {
  1301. return __sb_.is_open();
  1302. }
  1303. template <class _CharT, class _Traits>
  1304. void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1305. if (__sb_.open(__s, __mode))
  1306. this->clear();
  1307. else
  1308. this->setstate(ios_base::failbit);
  1309. }
  1310. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1311. template <class _CharT, class _Traits>
  1312. void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1313. if (__sb_.open(__s, __mode))
  1314. this->clear();
  1315. else
  1316. this->setstate(ios_base::failbit);
  1317. }
  1318. # endif
  1319. template <class _CharT, class _Traits>
  1320. void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1321. if (__sb_.open(__s, __mode))
  1322. this->clear();
  1323. else
  1324. this->setstate(ios_base::failbit);
  1325. }
  1326. template <class _CharT, class _Traits>
  1327. inline void basic_fstream<_CharT, _Traits>::close() {
  1328. if (__sb_.close() == nullptr)
  1329. this->setstate(ios_base::failbit);
  1330. }
  1331. # if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
  1332. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
  1333. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
  1334. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
  1335. # endif
  1336. _LIBCPP_END_NAMESPACE_STD
  1337. #endif // _LIBCPP_HAS_NO_FILESYSTEM
  1338. _LIBCPP_POP_MACROS
  1339. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  1340. # include <atomic>
  1341. # include <concepts>
  1342. # include <cstdlib>
  1343. # include <iosfwd>
  1344. # include <limits>
  1345. # include <mutex>
  1346. # include <new>
  1347. # include <stdexcept>
  1348. # include <type_traits>
  1349. #endif
  1350. #endif // _LIBCPP_FSTREAM