fstream 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568
  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. // There have been no file operations yet, which allows setting unbuffered
  264. // I/O mode.
  265. static const ios_base::openmode __no_io_operations = ios_base::trunc;
  266. // Unbuffered I/O mode has been requested.
  267. static const ios_base::openmode __use_unbuffered_io = ios_base::ate;
  268. // Used to track the currently used mode and track whether the output should
  269. // be unbuffered.
  270. // [filebuf.virtuals]/12
  271. // If setbuf(0, 0) is called on a stream before any I/O has occurred on
  272. // that stream, the stream becomes unbuffered. Otherwise the results are
  273. // implementation-defined.
  274. // This allows calling setbuf(0, 0)
  275. // - before opening a file,
  276. // - after opening a file, before
  277. // - a read
  278. // - a write
  279. // - a seek.
  280. // Note that opening a file with ios_base::ate does a seek operation.
  281. // Normally underflow, overflow, and sync change this flag to ios_base::in,
  282. // ios_base_out, or 0.
  283. //
  284. // The ios_base::trunc and ios_base::ate flags are not used in __cm_. They
  285. // are used to track the state of the unbuffered request. For readability
  286. // they have the aliases __no_io_operations and __use_unbuffered_io
  287. // respectively.
  288. //
  289. // The __no_io_operations and __use_unbuffered_io flags are used in the
  290. // following way:
  291. // - __no_io_operations is set upon construction to indicate the unbuffered
  292. // state can be set.
  293. // - When requesting unbuffered output:
  294. // - If the file is open it sets the mode.
  295. // - Else places a request by adding the __use_unbuffered_io flag.
  296. // - When a file is opened it checks whether both __no_io_operations and
  297. // __use_unbuffered_io are set. If so switches to unbuffered mode.
  298. // - All file I/O operations change the mode effectively clearing the
  299. // __no_io_operations and __use_unbuffered_io flags.
  300. ios_base::openmode __cm_;
  301. bool __owns_eb_;
  302. bool __owns_ib_;
  303. bool __always_noconv_;
  304. bool __read_mode();
  305. void __write_mode();
  306. _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
  307. // There are multiple (__)open function, they use different C-API open
  308. // function. After that call these functions behave the same. This function
  309. // does that part and determines the final return value.
  310. _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
  311. __file_ = __file;
  312. if (!__file_)
  313. return nullptr;
  314. __om_ = __mode;
  315. if (__cm_ == (__no_io_operations | __use_unbuffered_io)) {
  316. std::setbuf(__file_, nullptr);
  317. __cm_ = 0;
  318. }
  319. if (__mode & ios_base::ate) {
  320. __cm_ = 0;
  321. if (fseek(__file_, 0, SEEK_END)) {
  322. fclose(__file_);
  323. __file_ = nullptr;
  324. return nullptr;
  325. }
  326. }
  327. return this;
  328. }
  329. // If the file is already open, switch to unbuffered mode. Otherwise, record
  330. // the request to use unbuffered mode so that we use that mode when we
  331. // eventually open the file.
  332. _LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode(char_type* __s, streamsize __n) {
  333. if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) {
  334. if (__file_) {
  335. std::setbuf(__file_, nullptr);
  336. __cm_ = 0;
  337. } else {
  338. __cm_ = __no_io_operations | __use_unbuffered_io;
  339. }
  340. }
  341. }
  342. };
  343. template <class _CharT, class _Traits>
  344. basic_filebuf<_CharT, _Traits>::basic_filebuf()
  345. : __extbuf_(nullptr),
  346. __extbufnext_(nullptr),
  347. __extbufend_(nullptr),
  348. __ebs_(0),
  349. __intbuf_(nullptr),
  350. __ibs_(0),
  351. __file_(nullptr),
  352. __cv_(nullptr),
  353. __st_(),
  354. __st_last_(),
  355. __om_(0),
  356. __cm_(__no_io_operations),
  357. __owns_eb_(false),
  358. __owns_ib_(false),
  359. __always_noconv_(false) {
  360. if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
  361. __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
  362. __always_noconv_ = __cv_->always_noconv();
  363. }
  364. setbuf(nullptr, 4096);
  365. }
  366. template <class _CharT, class _Traits>
  367. basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
  368. if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
  369. __extbuf_ = __extbuf_min_;
  370. __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
  371. __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
  372. } else {
  373. __extbuf_ = __rhs.__extbuf_;
  374. __extbufnext_ = __rhs.__extbufnext_;
  375. __extbufend_ = __rhs.__extbufend_;
  376. }
  377. __ebs_ = __rhs.__ebs_;
  378. __intbuf_ = __rhs.__intbuf_;
  379. __ibs_ = __rhs.__ibs_;
  380. __file_ = __rhs.__file_;
  381. __cv_ = __rhs.__cv_;
  382. __st_ = __rhs.__st_;
  383. __st_last_ = __rhs.__st_last_;
  384. __om_ = __rhs.__om_;
  385. __cm_ = __rhs.__cm_;
  386. __owns_eb_ = __rhs.__owns_eb_;
  387. __owns_ib_ = __rhs.__owns_ib_;
  388. __always_noconv_ = __rhs.__always_noconv_;
  389. if (__rhs.pbase()) {
  390. if (__rhs.pbase() == __rhs.__intbuf_)
  391. this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
  392. else
  393. this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
  394. this->__pbump(__rhs.pptr() - __rhs.pbase());
  395. } else if (__rhs.eback()) {
  396. if (__rhs.eback() == __rhs.__intbuf_)
  397. this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
  398. else
  399. this->setg((char_type*)__extbuf_,
  400. (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
  401. (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
  402. }
  403. __rhs.__extbuf_ = nullptr;
  404. __rhs.__extbufnext_ = nullptr;
  405. __rhs.__extbufend_ = nullptr;
  406. __rhs.__ebs_ = 0;
  407. __rhs.__intbuf_ = 0;
  408. __rhs.__ibs_ = 0;
  409. __rhs.__file_ = nullptr;
  410. __rhs.__st_ = state_type();
  411. __rhs.__st_last_ = state_type();
  412. __rhs.__om_ = 0;
  413. __rhs.__cm_ = 0;
  414. __rhs.__owns_eb_ = false;
  415. __rhs.__owns_ib_ = false;
  416. __rhs.setg(0, 0, 0);
  417. __rhs.setp(0, 0);
  418. }
  419. template <class _CharT, class _Traits>
  420. inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
  421. close();
  422. swap(__rhs);
  423. return *this;
  424. }
  425. template <class _CharT, class _Traits>
  426. basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
  427. # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  428. try {
  429. # endif // _LIBCPP_HAS_NO_EXCEPTIONS
  430. close();
  431. # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  432. } catch (...) {
  433. }
  434. # endif // _LIBCPP_HAS_NO_EXCEPTIONS
  435. if (__owns_eb_)
  436. delete[] __extbuf_;
  437. if (__owns_ib_)
  438. delete[] __intbuf_;
  439. }
  440. template <class _CharT, class _Traits>
  441. void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
  442. basic_streambuf<char_type, traits_type>::swap(__rhs);
  443. if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
  444. // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
  445. std::swap(__extbuf_, __rhs.__extbuf_);
  446. std::swap(__extbufnext_, __rhs.__extbufnext_);
  447. std::swap(__extbufend_, __rhs.__extbufend_);
  448. } else {
  449. ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
  450. ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
  451. ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
  452. ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
  453. if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
  454. // *this uses the small buffer, but __rhs doesn't.
  455. __extbuf_ = __rhs.__extbuf_;
  456. __rhs.__extbuf_ = __rhs.__extbuf_min_;
  457. std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
  458. } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
  459. // *this doesn't use the small buffer, but __rhs does.
  460. __rhs.__extbuf_ = __extbuf_;
  461. __extbuf_ = __extbuf_min_;
  462. std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
  463. } else {
  464. // Both *this and __rhs use the small buffer.
  465. char __tmp[sizeof(__extbuf_min_)];
  466. std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
  467. std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
  468. std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
  469. }
  470. __extbufnext_ = __extbuf_ + __rn;
  471. __extbufend_ = __extbuf_ + __re;
  472. __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
  473. __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
  474. }
  475. std::swap(__ebs_, __rhs.__ebs_);
  476. std::swap(__intbuf_, __rhs.__intbuf_);
  477. std::swap(__ibs_, __rhs.__ibs_);
  478. std::swap(__file_, __rhs.__file_);
  479. std::swap(__cv_, __rhs.__cv_);
  480. std::swap(__st_, __rhs.__st_);
  481. std::swap(__st_last_, __rhs.__st_last_);
  482. std::swap(__om_, __rhs.__om_);
  483. std::swap(__cm_, __rhs.__cm_);
  484. std::swap(__owns_eb_, __rhs.__owns_eb_);
  485. std::swap(__owns_ib_, __rhs.__owns_ib_);
  486. std::swap(__always_noconv_, __rhs.__always_noconv_);
  487. if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
  488. ptrdiff_t __n = this->gptr() - this->eback();
  489. ptrdiff_t __e = this->egptr() - this->eback();
  490. this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
  491. } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
  492. ptrdiff_t __n = this->pptr() - this->pbase();
  493. ptrdiff_t __e = this->epptr() - this->pbase();
  494. this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
  495. this->__pbump(__n);
  496. }
  497. if (__rhs.eback() == (char_type*)__extbuf_min_) {
  498. ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
  499. ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
  500. __rhs.setg(
  501. (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
  502. } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
  503. ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
  504. ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
  505. __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
  506. __rhs.__pbump(__n);
  507. }
  508. }
  509. template <class _CharT, class _Traits>
  510. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
  511. __x.swap(__y);
  512. }
  513. template <class _CharT, class _Traits>
  514. inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
  515. return __file_ != nullptr;
  516. }
  517. template <class _CharT, class _Traits>
  518. const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
  519. switch (__mode & ~ios_base::ate) {
  520. case ios_base::out:
  521. case ios_base::out | ios_base::trunc:
  522. return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
  523. case ios_base::out | ios_base::app:
  524. case ios_base::app:
  525. return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
  526. case ios_base::in:
  527. return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
  528. case ios_base::in | ios_base::out:
  529. return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  530. case ios_base::in | ios_base::out | ios_base::trunc:
  531. return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  532. case ios_base::in | ios_base::out | ios_base::app:
  533. case ios_base::in | ios_base::app:
  534. return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  535. case ios_base::out | ios_base::binary:
  536. case ios_base::out | ios_base::trunc | ios_base::binary:
  537. return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  538. case ios_base::out | ios_base::app | ios_base::binary:
  539. case ios_base::app | ios_base::binary:
  540. return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
  541. case ios_base::in | ios_base::binary:
  542. return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  543. case ios_base::in | ios_base::out | ios_base::binary:
  544. return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  545. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
  546. return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  547. case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  548. case ios_base::in | ios_base::app | ios_base::binary:
  549. return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  550. # if _LIBCPP_STD_VER >= 23
  551. case ios_base::out | ios_base::noreplace:
  552. case ios_base::out | ios_base::trunc | ios_base::noreplace:
  553. return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  554. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
  555. return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
  556. case ios_base::out | ios_base::binary | ios_base::noreplace:
  557. case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  558. return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  559. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  560. return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  561. # endif // _LIBCPP_STD_VER >= 23
  562. default:
  563. return nullptr;
  564. }
  565. __libcpp_unreachable();
  566. }
  567. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  568. template <class _CharT, class _Traits>
  569. const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
  570. switch (__mode & ~ios_base::ate) {
  571. case ios_base::out:
  572. case ios_base::out | ios_base::trunc:
  573. return L"w";
  574. case ios_base::out | ios_base::app:
  575. case ios_base::app:
  576. return L"a";
  577. case ios_base::in:
  578. return L"r";
  579. case ios_base::in | ios_base::out:
  580. return L"r+";
  581. case ios_base::in | ios_base::out | ios_base::trunc:
  582. return L"w+";
  583. case ios_base::in | ios_base::out | ios_base::app:
  584. case ios_base::in | ios_base::app:
  585. return L"a+";
  586. case ios_base::out | ios_base::binary:
  587. case ios_base::out | ios_base::trunc | ios_base::binary:
  588. return L"wb";
  589. case ios_base::out | ios_base::app | ios_base::binary:
  590. case ios_base::app | ios_base::binary:
  591. return L"ab";
  592. case ios_base::in | ios_base::binary:
  593. return L"rb";
  594. case ios_base::in | ios_base::out | ios_base::binary:
  595. return L"r+b";
  596. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
  597. return L"w+b";
  598. case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  599. case ios_base::in | ios_base::app | ios_base::binary:
  600. return L"a+b";
  601. # if _LIBCPP_STD_VER >= 23
  602. case ios_base::out | ios_base::noreplace:
  603. case ios_base::out | ios_base::trunc | ios_base::noreplace:
  604. return L"wx";
  605. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
  606. return L"w+x";
  607. case ios_base::out | ios_base::binary | ios_base::noreplace:
  608. case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  609. return L"wbx";
  610. case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
  611. return L"w+bx";
  612. # endif // _LIBCPP_STD_VER >= 23
  613. default:
  614. return nullptr;
  615. }
  616. __libcpp_unreachable();
  617. }
  618. # endif
  619. template <class _CharT, class _Traits>
  620. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  621. if (__file_)
  622. return nullptr;
  623. const char* __mdstr = __make_mdstring(__mode);
  624. if (!__mdstr)
  625. return nullptr;
  626. return __do_open(fopen(__s, __mdstr), __mode);
  627. }
  628. template <class _CharT, class _Traits>
  629. inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  630. if (__file_)
  631. return nullptr;
  632. const char* __mdstr = __make_mdstring(__mode);
  633. if (!__mdstr)
  634. return nullptr;
  635. return __do_open(fdopen(__fd, __mdstr), __mode);
  636. }
  637. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  638. // This is basically the same as the char* overload except that it uses _wfopen
  639. // and long mode strings.
  640. template <class _CharT, class _Traits>
  641. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  642. if (__file_)
  643. return nullptr;
  644. const wchar_t* __mdstr = __make_mdwstring(__mode);
  645. if (!__mdstr)
  646. return nullptr;
  647. return __do_open(_wfopen(__s, __mdstr), __mode);
  648. }
  649. # endif
  650. template <class _CharT, class _Traits>
  651. inline basic_filebuf<_CharT, _Traits>*
  652. basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  653. return open(__s.c_str(), __mode);
  654. }
  655. template <class _CharT, class _Traits>
  656. basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
  657. basic_filebuf<_CharT, _Traits>* __rt = nullptr;
  658. if (__file_) {
  659. __rt = this;
  660. unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
  661. if (sync())
  662. __rt = nullptr;
  663. if (fclose(__h.release()))
  664. __rt = nullptr;
  665. __file_ = nullptr;
  666. setbuf(0, 0);
  667. }
  668. return __rt;
  669. }
  670. template <class _CharT, class _Traits>
  671. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
  672. if (__file_ == nullptr)
  673. return traits_type::eof();
  674. bool __initial = __read_mode();
  675. char_type __1buf;
  676. if (this->gptr() == nullptr)
  677. this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
  678. const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
  679. int_type __c = traits_type::eof();
  680. if (this->gptr() == this->egptr()) {
  681. std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
  682. if (__always_noconv_) {
  683. size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
  684. __nmemb = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
  685. if (__nmemb != 0) {
  686. this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
  687. __c = traits_type::to_int_type(*this->gptr());
  688. }
  689. } else {
  690. if (__extbufend_ != __extbufnext_) {
  691. _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
  692. _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
  693. std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
  694. }
  695. __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
  696. __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
  697. size_t __nmemb =
  698. std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
  699. codecvt_base::result __r;
  700. __st_last_ = __st_;
  701. size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
  702. if (__nr != 0) {
  703. if (!__cv_)
  704. __throw_bad_cast();
  705. __extbufend_ = __extbufnext_ + __nr;
  706. char_type* __inext;
  707. __r = __cv_->in(
  708. __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
  709. if (__r == codecvt_base::noconv) {
  710. this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
  711. __c = traits_type::to_int_type(*this->gptr());
  712. } else if (__inext != this->eback() + __unget_sz) {
  713. this->setg(this->eback(), this->eback() + __unget_sz, __inext);
  714. __c = traits_type::to_int_type(*this->gptr());
  715. }
  716. }
  717. }
  718. } else
  719. __c = traits_type::to_int_type(*this->gptr());
  720. if (this->eback() == &__1buf)
  721. this->setg(nullptr, nullptr, nullptr);
  722. return __c;
  723. }
  724. template <class _CharT, class _Traits>
  725. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
  726. if (__file_ && this->eback() < this->gptr()) {
  727. if (traits_type::eq_int_type(__c, traits_type::eof())) {
  728. this->gbump(-1);
  729. return traits_type::not_eof(__c);
  730. }
  731. if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
  732. this->gbump(-1);
  733. *this->gptr() = traits_type::to_char_type(__c);
  734. return __c;
  735. }
  736. }
  737. return traits_type::eof();
  738. }
  739. template <class _CharT, class _Traits>
  740. typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
  741. if (__file_ == nullptr)
  742. return traits_type::eof();
  743. __write_mode();
  744. char_type __1buf;
  745. char_type* __pb_save = this->pbase();
  746. char_type* __epb_save = this->epptr();
  747. if (!traits_type::eq_int_type(__c, traits_type::eof())) {
  748. if (this->pptr() == nullptr)
  749. this->setp(&__1buf, &__1buf + 1);
  750. *this->pptr() = traits_type::to_char_type(__c);
  751. this->pbump(1);
  752. }
  753. if (this->pptr() != this->pbase()) {
  754. if (__always_noconv_) {
  755. size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
  756. if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
  757. return traits_type::eof();
  758. } else {
  759. char* __extbe = __extbuf_;
  760. codecvt_base::result __r;
  761. do {
  762. if (!__cv_)
  763. __throw_bad_cast();
  764. const char_type* __e;
  765. __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
  766. if (__e == this->pbase())
  767. return traits_type::eof();
  768. if (__r == codecvt_base::noconv) {
  769. size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
  770. if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
  771. return traits_type::eof();
  772. } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
  773. size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
  774. if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
  775. return traits_type::eof();
  776. if (__r == codecvt_base::partial) {
  777. this->setp(const_cast<char_type*>(__e), this->pptr());
  778. this->__pbump(this->epptr() - this->pbase());
  779. }
  780. } else
  781. return traits_type::eof();
  782. } while (__r == codecvt_base::partial);
  783. }
  784. this->setp(__pb_save, __epb_save);
  785. }
  786. return traits_type::not_eof(__c);
  787. }
  788. template <class _CharT, class _Traits>
  789. basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
  790. this->setg(nullptr, nullptr, nullptr);
  791. this->setp(nullptr, nullptr);
  792. __request_unbuffered_mode(__s, __n);
  793. if (__owns_eb_)
  794. delete[] __extbuf_;
  795. if (__owns_ib_)
  796. delete[] __intbuf_;
  797. __ebs_ = __n;
  798. if (__ebs_ > sizeof(__extbuf_min_)) {
  799. if (__always_noconv_ && __s) {
  800. __extbuf_ = (char*)__s;
  801. __owns_eb_ = false;
  802. } else {
  803. __extbuf_ = new char[__ebs_];
  804. __owns_eb_ = true;
  805. }
  806. } else {
  807. __extbuf_ = __extbuf_min_;
  808. __ebs_ = sizeof(__extbuf_min_);
  809. __owns_eb_ = false;
  810. }
  811. if (!__always_noconv_) {
  812. __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
  813. if (__s && __ibs_ > sizeof(__extbuf_min_)) {
  814. __intbuf_ = __s;
  815. __owns_ib_ = false;
  816. } else {
  817. __intbuf_ = new char_type[__ibs_];
  818. __owns_ib_ = true;
  819. }
  820. } else {
  821. __ibs_ = 0;
  822. __intbuf_ = nullptr;
  823. __owns_ib_ = false;
  824. }
  825. return this;
  826. }
  827. template <class _CharT, class _Traits>
  828. typename basic_filebuf<_CharT, _Traits>::pos_type
  829. basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
  830. if (!__cv_)
  831. __throw_bad_cast();
  832. int __width = __cv_->encoding();
  833. if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
  834. return pos_type(off_type(-1));
  835. // __width > 0 || __off == 0
  836. int __whence;
  837. switch (__way) {
  838. case ios_base::beg:
  839. __whence = SEEK_SET;
  840. break;
  841. case ios_base::cur:
  842. __whence = SEEK_CUR;
  843. break;
  844. case ios_base::end:
  845. __whence = SEEK_END;
  846. break;
  847. default:
  848. return pos_type(off_type(-1));
  849. }
  850. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  851. if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
  852. return pos_type(off_type(-1));
  853. pos_type __r = ftell(__file_);
  854. # else
  855. if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
  856. return pos_type(off_type(-1));
  857. pos_type __r = ftello(__file_);
  858. # endif
  859. __r.state(__st_);
  860. return __r;
  861. }
  862. template <class _CharT, class _Traits>
  863. typename basic_filebuf<_CharT, _Traits>::pos_type
  864. basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
  865. if (__file_ == nullptr || sync())
  866. return pos_type(off_type(-1));
  867. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  868. if (fseek(__file_, __sp, SEEK_SET))
  869. return pos_type(off_type(-1));
  870. # else
  871. if (::fseeko(__file_, __sp, SEEK_SET))
  872. return pos_type(off_type(-1));
  873. # endif
  874. __st_ = __sp.state();
  875. return __sp;
  876. }
  877. template <class _CharT, class _Traits>
  878. int basic_filebuf<_CharT, _Traits>::sync() {
  879. if (__file_ == nullptr)
  880. return 0;
  881. if (!__cv_)
  882. __throw_bad_cast();
  883. if (__cm_ & ios_base::out) {
  884. if (this->pptr() != this->pbase())
  885. if (overflow() == traits_type::eof())
  886. return -1;
  887. codecvt_base::result __r;
  888. do {
  889. char* __extbe;
  890. __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
  891. size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
  892. if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
  893. return -1;
  894. } while (__r == codecvt_base::partial);
  895. if (__r == codecvt_base::error)
  896. return -1;
  897. if (fflush(__file_))
  898. return -1;
  899. } else if (__cm_ & ios_base::in) {
  900. off_type __c;
  901. state_type __state = __st_last_;
  902. bool __update_st = false;
  903. if (__always_noconv_)
  904. __c = this->egptr() - this->gptr();
  905. else {
  906. int __width = __cv_->encoding();
  907. __c = __extbufend_ - __extbufnext_;
  908. if (__width > 0)
  909. __c += __width * (this->egptr() - this->gptr());
  910. else {
  911. if (this->gptr() != this->egptr()) {
  912. const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
  913. __c += __extbufnext_ - __extbuf_ - __off;
  914. __update_st = true;
  915. }
  916. }
  917. }
  918. # if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
  919. if (fseek(__file_, -__c, SEEK_CUR))
  920. return -1;
  921. # else
  922. if (::fseeko(__file_, -__c, SEEK_CUR))
  923. return -1;
  924. # endif
  925. if (__update_st)
  926. __st_ = __state;
  927. __extbufnext_ = __extbufend_ = __extbuf_;
  928. this->setg(nullptr, nullptr, nullptr);
  929. __cm_ = 0;
  930. }
  931. return 0;
  932. }
  933. template <class _CharT, class _Traits>
  934. void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
  935. sync();
  936. __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
  937. bool __old_anc = __always_noconv_;
  938. __always_noconv_ = __cv_->always_noconv();
  939. if (__old_anc != __always_noconv_) {
  940. this->setg(nullptr, nullptr, nullptr);
  941. this->setp(nullptr, nullptr);
  942. // invariant, char_type is char, else we couldn't get here
  943. if (__always_noconv_) // need to dump __intbuf_
  944. {
  945. if (__owns_eb_)
  946. delete[] __extbuf_;
  947. __owns_eb_ = __owns_ib_;
  948. __ebs_ = __ibs_;
  949. __extbuf_ = (char*)__intbuf_;
  950. __ibs_ = 0;
  951. __intbuf_ = nullptr;
  952. __owns_ib_ = false;
  953. } else // need to obtain an __intbuf_.
  954. { // If __extbuf_ is user-supplied, use it, else new __intbuf_
  955. if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
  956. __ibs_ = __ebs_;
  957. __intbuf_ = (char_type*)__extbuf_;
  958. __owns_ib_ = false;
  959. __extbuf_ = new char[__ebs_];
  960. __owns_eb_ = true;
  961. } else {
  962. __ibs_ = __ebs_;
  963. __intbuf_ = new char_type[__ibs_];
  964. __owns_ib_ = true;
  965. }
  966. }
  967. }
  968. }
  969. template <class _CharT, class _Traits>
  970. bool basic_filebuf<_CharT, _Traits>::__read_mode() {
  971. if (!(__cm_ & ios_base::in)) {
  972. this->setp(nullptr, nullptr);
  973. if (__always_noconv_)
  974. this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
  975. else
  976. this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
  977. __cm_ = ios_base::in;
  978. return true;
  979. }
  980. return false;
  981. }
  982. template <class _CharT, class _Traits>
  983. void basic_filebuf<_CharT, _Traits>::__write_mode() {
  984. if (!(__cm_ & ios_base::out)) {
  985. this->setg(nullptr, nullptr, nullptr);
  986. if (__ebs_ > sizeof(__extbuf_min_)) {
  987. if (__always_noconv_)
  988. this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
  989. else
  990. this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
  991. } else
  992. this->setp(nullptr, nullptr);
  993. __cm_ = ios_base::out;
  994. }
  995. }
  996. // basic_ifstream
  997. template <class _CharT, class _Traits>
  998. class _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
  999. public:
  1000. typedef _CharT char_type;
  1001. typedef _Traits traits_type;
  1002. typedef typename traits_type::int_type int_type;
  1003. typedef typename traits_type::pos_type pos_type;
  1004. typedef typename traits_type::off_type off_type;
  1005. # if _LIBCPP_STD_VER >= 26
  1006. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  1007. # endif
  1008. _LIBCPP_HIDE_FROM_ABI basic_ifstream();
  1009. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
  1010. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1011. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
  1012. # endif
  1013. _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
  1014. # if _LIBCPP_STD_VER >= 17
  1015. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(
  1016. const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
  1017. : basic_ifstream(__p.c_str(), __mode) {}
  1018. # endif // _LIBCPP_STD_VER >= 17
  1019. _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
  1020. _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
  1021. _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
  1022. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  1023. # if _LIBCPP_STD_VER >= 26
  1024. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  1025. # endif
  1026. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  1027. void open(const char* __s, ios_base::openmode __mode = ios_base::in);
  1028. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1029. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
  1030. # endif
  1031. void open(const string& __s, ios_base::openmode __mode = ios_base::in);
  1032. # if _LIBCPP_STD_VER >= 17
  1033. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  1034. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
  1035. return open(__p.c_str(), __mode);
  1036. }
  1037. # endif // _LIBCPP_STD_VER >= 17
  1038. _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  1039. _LIBCPP_HIDE_FROM_ABI void close();
  1040. private:
  1041. basic_filebuf<char_type, traits_type> __sb_;
  1042. };
  1043. template <class _CharT, class _Traits>
  1044. inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
  1045. template <class _CharT, class _Traits>
  1046. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
  1047. : basic_istream<char_type, traits_type>(&__sb_) {
  1048. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  1049. this->setstate(ios_base::failbit);
  1050. }
  1051. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1052. template <class _CharT, class _Traits>
  1053. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
  1054. : basic_istream<char_type, traits_type>(&__sb_) {
  1055. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  1056. this->setstate(ios_base::failbit);
  1057. }
  1058. # endif
  1059. template <class _CharT, class _Traits>
  1060. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
  1061. : basic_istream<char_type, traits_type>(&__sb_) {
  1062. if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
  1063. this->setstate(ios_base::failbit);
  1064. }
  1065. template <class _CharT, class _Traits>
  1066. inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
  1067. : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1068. this->set_rdbuf(&__sb_);
  1069. }
  1070. template <class _CharT, class _Traits>
  1071. inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
  1072. basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
  1073. __sb_ = std::move(__rhs.__sb_);
  1074. return *this;
  1075. }
  1076. template <class _CharT, class _Traits>
  1077. inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
  1078. basic_istream<char_type, traits_type>::swap(__rhs);
  1079. __sb_.swap(__rhs.__sb_);
  1080. }
  1081. template <class _CharT, class _Traits>
  1082. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
  1083. __x.swap(__y);
  1084. }
  1085. template <class _CharT, class _Traits>
  1086. inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
  1087. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1088. }
  1089. template <class _CharT, class _Traits>
  1090. inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
  1091. return __sb_.is_open();
  1092. }
  1093. template <class _CharT, class _Traits>
  1094. void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1095. if (__sb_.open(__s, __mode | ios_base::in))
  1096. this->clear();
  1097. else
  1098. this->setstate(ios_base::failbit);
  1099. }
  1100. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1101. template <class _CharT, class _Traits>
  1102. void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1103. if (__sb_.open(__s, __mode | ios_base::in))
  1104. this->clear();
  1105. else
  1106. this->setstate(ios_base::failbit);
  1107. }
  1108. # endif
  1109. template <class _CharT, class _Traits>
  1110. void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1111. if (__sb_.open(__s, __mode | ios_base::in))
  1112. this->clear();
  1113. else
  1114. this->setstate(ios_base::failbit);
  1115. }
  1116. template <class _CharT, class _Traits>
  1117. inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  1118. if (__sb_.__open(__fd, __mode | ios_base::in))
  1119. this->clear();
  1120. else
  1121. this->setstate(ios_base::failbit);
  1122. }
  1123. template <class _CharT, class _Traits>
  1124. inline void basic_ifstream<_CharT, _Traits>::close() {
  1125. if (__sb_.close() == 0)
  1126. this->setstate(ios_base::failbit);
  1127. }
  1128. // basic_ofstream
  1129. template <class _CharT, class _Traits>
  1130. class _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
  1131. public:
  1132. typedef _CharT char_type;
  1133. typedef _Traits traits_type;
  1134. typedef typename traits_type::int_type int_type;
  1135. typedef typename traits_type::pos_type pos_type;
  1136. typedef typename traits_type::off_type off_type;
  1137. # if _LIBCPP_STD_VER >= 26
  1138. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  1139. # endif
  1140. _LIBCPP_HIDE_FROM_ABI basic_ofstream();
  1141. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
  1142. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1143. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
  1144. # endif
  1145. _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
  1146. # if _LIBCPP_STD_VER >= 17
  1147. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(
  1148. const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
  1149. : basic_ofstream(__p.c_str(), __mode) {}
  1150. # endif // _LIBCPP_STD_VER >= 17
  1151. _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
  1152. _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
  1153. _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
  1154. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  1155. # if _LIBCPP_STD_VER >= 26
  1156. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  1157. # endif
  1158. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  1159. void open(const char* __s, ios_base::openmode __mode = ios_base::out);
  1160. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1161. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
  1162. # endif
  1163. void open(const string& __s, ios_base::openmode __mode = ios_base::out);
  1164. # if _LIBCPP_STD_VER >= 17
  1165. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  1166. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
  1167. return open(__p.c_str(), __mode);
  1168. }
  1169. # endif // _LIBCPP_STD_VER >= 17
  1170. _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  1171. _LIBCPP_HIDE_FROM_ABI void close();
  1172. private:
  1173. basic_filebuf<char_type, traits_type> __sb_;
  1174. };
  1175. template <class _CharT, class _Traits>
  1176. inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
  1177. template <class _CharT, class _Traits>
  1178. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
  1179. : basic_ostream<char_type, traits_type>(&__sb_) {
  1180. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1181. this->setstate(ios_base::failbit);
  1182. }
  1183. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1184. template <class _CharT, class _Traits>
  1185. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
  1186. : basic_ostream<char_type, traits_type>(&__sb_) {
  1187. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1188. this->setstate(ios_base::failbit);
  1189. }
  1190. # endif
  1191. template <class _CharT, class _Traits>
  1192. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
  1193. : basic_ostream<char_type, traits_type>(&__sb_) {
  1194. if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
  1195. this->setstate(ios_base::failbit);
  1196. }
  1197. template <class _CharT, class _Traits>
  1198. inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
  1199. : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1200. this->set_rdbuf(&__sb_);
  1201. }
  1202. template <class _CharT, class _Traits>
  1203. inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
  1204. basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
  1205. __sb_ = std::move(__rhs.__sb_);
  1206. return *this;
  1207. }
  1208. template <class _CharT, class _Traits>
  1209. inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
  1210. basic_ostream<char_type, traits_type>::swap(__rhs);
  1211. __sb_.swap(__rhs.__sb_);
  1212. }
  1213. template <class _CharT, class _Traits>
  1214. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
  1215. __x.swap(__y);
  1216. }
  1217. template <class _CharT, class _Traits>
  1218. inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
  1219. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1220. }
  1221. template <class _CharT, class _Traits>
  1222. inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
  1223. return __sb_.is_open();
  1224. }
  1225. template <class _CharT, class _Traits>
  1226. void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1227. if (__sb_.open(__s, __mode | ios_base::out))
  1228. this->clear();
  1229. else
  1230. this->setstate(ios_base::failbit);
  1231. }
  1232. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1233. template <class _CharT, class _Traits>
  1234. void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1235. if (__sb_.open(__s, __mode | ios_base::out))
  1236. this->clear();
  1237. else
  1238. this->setstate(ios_base::failbit);
  1239. }
  1240. # endif
  1241. template <class _CharT, class _Traits>
  1242. void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1243. if (__sb_.open(__s, __mode | ios_base::out))
  1244. this->clear();
  1245. else
  1246. this->setstate(ios_base::failbit);
  1247. }
  1248. template <class _CharT, class _Traits>
  1249. inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  1250. if (__sb_.__open(__fd, __mode | ios_base::out))
  1251. this->clear();
  1252. else
  1253. this->setstate(ios_base::failbit);
  1254. }
  1255. template <class _CharT, class _Traits>
  1256. inline void basic_ofstream<_CharT, _Traits>::close() {
  1257. if (__sb_.close() == nullptr)
  1258. this->setstate(ios_base::failbit);
  1259. }
  1260. // basic_fstream
  1261. template <class _CharT, class _Traits>
  1262. class _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
  1263. public:
  1264. typedef _CharT char_type;
  1265. typedef _Traits traits_type;
  1266. typedef typename traits_type::int_type int_type;
  1267. typedef typename traits_type::pos_type pos_type;
  1268. typedef typename traits_type::off_type off_type;
  1269. # if _LIBCPP_STD_VER >= 26
  1270. using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
  1271. # endif
  1272. _LIBCPP_HIDE_FROM_ABI basic_fstream();
  1273. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
  1274. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1275. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1276. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
  1277. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1278. # endif
  1279. _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
  1280. ios_base::openmode __mode = ios_base::in | ios_base::out);
  1281. # if _LIBCPP_STD_VER >= 17
  1282. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
  1283. const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
  1284. : basic_fstream(__p.c_str(), __mode) {}
  1285. # endif // _LIBCPP_STD_VER >= 17
  1286. _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
  1287. _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
  1288. _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
  1289. _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
  1290. # if _LIBCPP_STD_VER >= 26
  1291. _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
  1292. # endif
  1293. _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  1294. _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1295. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1296. void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1297. # endif
  1298. _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
  1299. # if _LIBCPP_STD_VER >= 17
  1300. _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
  1301. open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
  1302. return open(__p.c_str(), __mode);
  1303. }
  1304. # endif // _LIBCPP_STD_VER >= 17
  1305. _LIBCPP_HIDE_FROM_ABI void close();
  1306. private:
  1307. basic_filebuf<char_type, traits_type> __sb_;
  1308. };
  1309. template <class _CharT, class _Traits>
  1310. inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
  1311. template <class _CharT, class _Traits>
  1312. inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
  1313. : basic_iostream<char_type, traits_type>(&__sb_) {
  1314. if (__sb_.open(__s, __mode) == nullptr)
  1315. this->setstate(ios_base::failbit);
  1316. }
  1317. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1318. template <class _CharT, class _Traits>
  1319. inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
  1320. : basic_iostream<char_type, traits_type>(&__sb_) {
  1321. if (__sb_.open(__s, __mode) == nullptr)
  1322. this->setstate(ios_base::failbit);
  1323. }
  1324. # endif
  1325. template <class _CharT, class _Traits>
  1326. inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
  1327. : basic_iostream<char_type, traits_type>(&__sb_) {
  1328. if (__sb_.open(__s, __mode) == nullptr)
  1329. this->setstate(ios_base::failbit);
  1330. }
  1331. template <class _CharT, class _Traits>
  1332. inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
  1333. : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  1334. this->set_rdbuf(&__sb_);
  1335. }
  1336. template <class _CharT, class _Traits>
  1337. inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
  1338. basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
  1339. __sb_ = std::move(__rhs.__sb_);
  1340. return *this;
  1341. }
  1342. template <class _CharT, class _Traits>
  1343. inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
  1344. basic_iostream<char_type, traits_type>::swap(__rhs);
  1345. __sb_.swap(__rhs.__sb_);
  1346. }
  1347. template <class _CharT, class _Traits>
  1348. inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
  1349. __x.swap(__y);
  1350. }
  1351. template <class _CharT, class _Traits>
  1352. inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
  1353. return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
  1354. }
  1355. template <class _CharT, class _Traits>
  1356. inline bool basic_fstream<_CharT, _Traits>::is_open() const {
  1357. return __sb_.is_open();
  1358. }
  1359. template <class _CharT, class _Traits>
  1360. void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  1361. if (__sb_.open(__s, __mode))
  1362. this->clear();
  1363. else
  1364. this->setstate(ios_base::failbit);
  1365. }
  1366. # ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
  1367. template <class _CharT, class _Traits>
  1368. void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  1369. if (__sb_.open(__s, __mode))
  1370. this->clear();
  1371. else
  1372. this->setstate(ios_base::failbit);
  1373. }
  1374. # endif
  1375. template <class _CharT, class _Traits>
  1376. void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  1377. if (__sb_.open(__s, __mode))
  1378. this->clear();
  1379. else
  1380. this->setstate(ios_base::failbit);
  1381. }
  1382. template <class _CharT, class _Traits>
  1383. inline void basic_fstream<_CharT, _Traits>::close() {
  1384. if (__sb_.close() == nullptr)
  1385. this->setstate(ios_base::failbit);
  1386. }
  1387. # if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
  1388. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
  1389. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
  1390. extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
  1391. # endif
  1392. _LIBCPP_END_NAMESPACE_STD
  1393. #endif // _LIBCPP_HAS_NO_FILESYSTEM
  1394. _LIBCPP_POP_MACROS
  1395. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  1396. # include <atomic>
  1397. # include <concepts>
  1398. # include <cstdlib>
  1399. # include <iosfwd>
  1400. # include <limits>
  1401. # include <mutex>
  1402. # include <new>
  1403. # include <stdexcept>
  1404. # include <type_traits>
  1405. #endif
  1406. #endif // _LIBCPP_FSTREAM