fstream 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. // File based streams -*- C++ -*-
  2. // Copyright (C) 1997-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/fstream
  21. * This is a Standard C++ Library header.
  22. */
  23. //
  24. // ISO C++ 14882: 27.8 File-based streams
  25. //
  26. #ifndef _GLIBCXX_FSTREAM
  27. #define _GLIBCXX_FSTREAM 1
  28. #pragma GCC system_header
  29. #include <istream>
  30. #include <ostream>
  31. #include <bits/codecvt.h>
  32. #include <cstdio> // For BUFSIZ
  33. #include <bits/basic_file.h> // For __basic_file, __c_lock
  34. #if __cplusplus >= 201103L
  35. #include <string> // For std::string overloads.
  36. #endif
  37. namespace std _GLIBCXX_VISIBILITY(default)
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. #if __cplusplus >= 201703L
  41. // Enable if _Path is a filesystem::path or experimental::filesystem::path
  42. template<typename _Path, typename _Result = _Path, typename _Path2
  43. = decltype(std::declval<_Path&>().make_preferred().filename())>
  44. using _If_fs_path = enable_if_t<is_same_v<_Path, _Path2>, _Result>;
  45. #endif // C++17
  46. // [27.8.1.1] template class basic_filebuf
  47. /**
  48. * @brief The actual work of input and output (for files).
  49. * @ingroup io
  50. *
  51. * @tparam _CharT Type of character stream.
  52. * @tparam _Traits Traits for character type, defaults to
  53. * char_traits<_CharT>.
  54. *
  55. * This class associates both its input and output sequence with an
  56. * external disk file, and maintains a joint file position for both
  57. * sequences. Many of its semantics are described in terms of similar
  58. * behavior in the Standard C Library's @c FILE streams.
  59. *
  60. * Requirements on traits_type, specific to this class:
  61. * - traits_type::pos_type must be fpos<traits_type::state_type>
  62. * - traits_type::off_type must be streamoff
  63. * - traits_type::state_type must be Assignable and DefaultConstructible,
  64. * - traits_type::state_type() must be the initial state for codecvt.
  65. */
  66. template<typename _CharT, typename _Traits>
  67. class basic_filebuf : public basic_streambuf<_CharT, _Traits>
  68. {
  69. #if __cplusplus >= 201103L
  70. template<typename _Tp>
  71. using __chk_state = __and_<is_copy_assignable<_Tp>,
  72. is_copy_constructible<_Tp>,
  73. is_default_constructible<_Tp>>;
  74. static_assert(__chk_state<typename _Traits::state_type>::value,
  75. "state_type must be CopyAssignable, CopyConstructible"
  76. " and DefaultConstructible");
  77. static_assert(is_same<typename _Traits::pos_type,
  78. fpos<typename _Traits::state_type>>::value,
  79. "pos_type must be fpos<state_type>");
  80. #endif
  81. public:
  82. // Types:
  83. typedef _CharT char_type;
  84. typedef _Traits traits_type;
  85. typedef typename traits_type::int_type int_type;
  86. typedef typename traits_type::pos_type pos_type;
  87. typedef typename traits_type::off_type off_type;
  88. typedef basic_streambuf<char_type, traits_type> __streambuf_type;
  89. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  90. typedef __basic_file<char> __file_type;
  91. typedef typename traits_type::state_type __state_type;
  92. typedef codecvt<char_type, char, __state_type> __codecvt_type;
  93. friend class ios_base; // For sync_with_stdio.
  94. protected:
  95. // Data Members:
  96. // MT lock inherited from libio or other low-level io library.
  97. __c_lock _M_lock;
  98. // External buffer.
  99. __file_type _M_file;
  100. /// Place to stash in || out || in | out settings for current filebuf.
  101. ios_base::openmode _M_mode;
  102. // Beginning state type for codecvt.
  103. __state_type _M_state_beg;
  104. // During output, the state that corresponds to pptr(),
  105. // during input, the state that corresponds to egptr() and
  106. // _M_ext_next.
  107. __state_type _M_state_cur;
  108. // Not used for output. During input, the state that corresponds
  109. // to eback() and _M_ext_buf.
  110. __state_type _M_state_last;
  111. /// Pointer to the beginning of internal buffer.
  112. char_type* _M_buf;
  113. /**
  114. * Actual size of internal buffer. This number is equal to the size
  115. * of the put area + 1 position, reserved for the overflow char of
  116. * a full area.
  117. */
  118. size_t _M_buf_size;
  119. // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
  120. bool _M_buf_allocated;
  121. /**
  122. * _M_reading == false && _M_writing == false for @b uncommitted mode;
  123. * _M_reading == true for @b read mode;
  124. * _M_writing == true for @b write mode;
  125. *
  126. * NB: _M_reading == true && _M_writing == true is unused.
  127. */
  128. bool _M_reading;
  129. bool _M_writing;
  130. //@{
  131. /**
  132. * Necessary bits for putback buffer management.
  133. *
  134. * @note pbacks of over one character are not currently supported.
  135. */
  136. char_type _M_pback;
  137. char_type* _M_pback_cur_save;
  138. char_type* _M_pback_end_save;
  139. bool _M_pback_init;
  140. //@}
  141. // Cached codecvt facet.
  142. const __codecvt_type* _M_codecvt;
  143. /**
  144. * Buffer for external characters. Used for input when
  145. * codecvt::always_noconv() == false. When valid, this corresponds
  146. * to eback().
  147. */
  148. char* _M_ext_buf;
  149. /**
  150. * Size of buffer held by _M_ext_buf.
  151. */
  152. streamsize _M_ext_buf_size;
  153. /**
  154. * Pointers into the buffer held by _M_ext_buf that delimit a
  155. * subsequence of bytes that have been read but not yet converted.
  156. * When valid, _M_ext_next corresponds to egptr().
  157. */
  158. const char* _M_ext_next;
  159. char* _M_ext_end;
  160. /**
  161. * Initializes pback buffers, and moves normal buffers to safety.
  162. * Assumptions:
  163. * _M_in_cur has already been moved back
  164. */
  165. void
  166. _M_create_pback()
  167. {
  168. if (!_M_pback_init)
  169. {
  170. _M_pback_cur_save = this->gptr();
  171. _M_pback_end_save = this->egptr();
  172. this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
  173. _M_pback_init = true;
  174. }
  175. }
  176. /**
  177. * Deactivates pback buffer contents, and restores normal buffer.
  178. * Assumptions:
  179. * The pback buffer has only moved forward.
  180. */
  181. void
  182. _M_destroy_pback() throw()
  183. {
  184. if (_M_pback_init)
  185. {
  186. // Length _M_in_cur moved in the pback buffer.
  187. _M_pback_cur_save += this->gptr() != this->eback();
  188. this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save);
  189. _M_pback_init = false;
  190. }
  191. }
  192. public:
  193. // Constructors/destructor:
  194. /**
  195. * @brief Does not open any files.
  196. *
  197. * The default constructor initializes the parent class using its
  198. * own default ctor.
  199. */
  200. basic_filebuf();
  201. #if __cplusplus >= 201103L
  202. basic_filebuf(const basic_filebuf&) = delete;
  203. basic_filebuf(basic_filebuf&&);
  204. #endif
  205. /**
  206. * @brief The destructor closes the file first.
  207. */
  208. virtual
  209. ~basic_filebuf()
  210. { this->close(); }
  211. #if __cplusplus >= 201103L
  212. basic_filebuf& operator=(const basic_filebuf&) = delete;
  213. basic_filebuf& operator=(basic_filebuf&&);
  214. void swap(basic_filebuf&);
  215. #endif
  216. // Members:
  217. /**
  218. * @brief Returns true if the external file is open.
  219. */
  220. bool
  221. is_open() const throw()
  222. { return _M_file.is_open(); }
  223. /**
  224. * @brief Opens an external file.
  225. * @param __s The name of the file.
  226. * @param __mode The open mode flags.
  227. * @return @c this on success, NULL on failure
  228. *
  229. * If a file is already open, this function immediately fails.
  230. * Otherwise it tries to open the file named @a __s using the flags
  231. * given in @a __mode.
  232. *
  233. * Table 92, adapted here, gives the relation between openmode
  234. * combinations and the equivalent @c fopen() flags.
  235. * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
  236. * and binary|in|app per DR 596)
  237. * <pre>
  238. * +---------------------------------------------------------+
  239. * | ios_base Flag combination stdio equivalent |
  240. * |binary in out trunc app |
  241. * +---------------------------------------------------------+
  242. * | + w |
  243. * | + + a |
  244. * | + a |
  245. * | + + w |
  246. * | + r |
  247. * | + + r+ |
  248. * | + + + w+ |
  249. * | + + + a+ |
  250. * | + + a+ |
  251. * +---------------------------------------------------------+
  252. * | + + wb |
  253. * | + + + ab |
  254. * | + + ab |
  255. * | + + + wb |
  256. * | + + rb |
  257. * | + + + r+b |
  258. * | + + + + w+b |
  259. * | + + + + a+b |
  260. * | + + + a+b |
  261. * +---------------------------------------------------------+
  262. * </pre>
  263. */
  264. __filebuf_type*
  265. open(const char* __s, ios_base::openmode __mode);
  266. #if __cplusplus >= 201103L
  267. /**
  268. * @brief Opens an external file.
  269. * @param __s The name of the file.
  270. * @param __mode The open mode flags.
  271. * @return @c this on success, NULL on failure
  272. */
  273. __filebuf_type*
  274. open(const std::string& __s, ios_base::openmode __mode)
  275. { return open(__s.c_str(), __mode); }
  276. #if __cplusplus >= 201703L
  277. /**
  278. * @brief Opens an external file.
  279. * @param __s The name of the file, as a filesystem::path.
  280. * @param __mode The open mode flags.
  281. * @return @c this on success, NULL on failure
  282. */
  283. template<typename _Path>
  284. _If_fs_path<_Path, __filebuf_type*>
  285. open(const _Path& __s, ios_base::openmode __mode)
  286. { return open(__s.c_str(), __mode); }
  287. #endif // C++17
  288. #endif // C++11
  289. /**
  290. * @brief Closes the currently associated file.
  291. * @return @c this on success, NULL on failure
  292. *
  293. * If no file is currently open, this function immediately fails.
  294. *
  295. * If a <em>put buffer area</em> exists, @c overflow(eof) is
  296. * called to flush all the characters. The file is then
  297. * closed.
  298. *
  299. * If any operations fail, this function also fails.
  300. */
  301. __filebuf_type*
  302. close();
  303. protected:
  304. void
  305. _M_allocate_internal_buffer();
  306. void
  307. _M_destroy_internal_buffer() throw();
  308. // [27.8.1.4] overridden virtual functions
  309. virtual streamsize
  310. showmanyc();
  311. // Stroustrup, 1998, p. 628
  312. // underflow() and uflow() functions are called to get the next
  313. // character from the real input source when the buffer is empty.
  314. // Buffered input uses underflow()
  315. virtual int_type
  316. underflow();
  317. virtual int_type
  318. pbackfail(int_type __c = _Traits::eof());
  319. // Stroustrup, 1998, p 648
  320. // The overflow() function is called to transfer characters to the
  321. // real output destination when the buffer is full. A call to
  322. // overflow(c) outputs the contents of the buffer plus the
  323. // character c.
  324. // 27.5.2.4.5
  325. // Consume some sequence of the characters in the pending sequence.
  326. virtual int_type
  327. overflow(int_type __c = _Traits::eof());
  328. // Convert internal byte sequence to external, char-based
  329. // sequence via codecvt.
  330. bool
  331. _M_convert_to_external(char_type*, streamsize);
  332. /**
  333. * @brief Manipulates the buffer.
  334. * @param __s Pointer to a buffer area.
  335. * @param __n Size of @a __s.
  336. * @return @c this
  337. *
  338. * If no file has been opened, and both @a __s and @a __n are zero, then
  339. * the stream becomes unbuffered. Otherwise, @c __s is used as a
  340. * buffer; see
  341. * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
  342. * for more.
  343. */
  344. virtual __streambuf_type*
  345. setbuf(char_type* __s, streamsize __n);
  346. virtual pos_type
  347. seekoff(off_type __off, ios_base::seekdir __way,
  348. ios_base::openmode __mode = ios_base::in | ios_base::out);
  349. virtual pos_type
  350. seekpos(pos_type __pos,
  351. ios_base::openmode __mode = ios_base::in | ios_base::out);
  352. // Common code for seekoff, seekpos, and overflow
  353. pos_type
  354. _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
  355. int
  356. _M_get_ext_pos(__state_type &__state);
  357. virtual int
  358. sync();
  359. virtual void
  360. imbue(const locale& __loc);
  361. virtual streamsize
  362. xsgetn(char_type* __s, streamsize __n);
  363. virtual streamsize
  364. xsputn(const char_type* __s, streamsize __n);
  365. // Flushes output buffer, then writes unshift sequence.
  366. bool
  367. _M_terminate_output();
  368. /**
  369. * This function sets the pointers of the internal buffer, both get
  370. * and put areas. Typically:
  371. *
  372. * __off == egptr() - eback() upon underflow/uflow (@b read mode);
  373. * __off == 0 upon overflow (@b write mode);
  374. * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode).
  375. *
  376. * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
  377. * reflects the actual allocated memory and the last cell is reserved
  378. * for the overflow char of a full put area.
  379. */
  380. void
  381. _M_set_buffer(streamsize __off)
  382. {
  383. const bool __testin = _M_mode & ios_base::in;
  384. const bool __testout = (_M_mode & ios_base::out
  385. || _M_mode & ios_base::app);
  386. if (__testin && __off > 0)
  387. this->setg(_M_buf, _M_buf, _M_buf + __off);
  388. else
  389. this->setg(_M_buf, _M_buf, _M_buf);
  390. if (__testout && __off == 0 && _M_buf_size > 1 )
  391. this->setp(_M_buf, _M_buf + _M_buf_size - 1);
  392. else
  393. this->setp(0, 0);
  394. }
  395. };
  396. // [27.8.1.5] Template class basic_ifstream
  397. /**
  398. * @brief Controlling input for files.
  399. * @ingroup io
  400. *
  401. * @tparam _CharT Type of character stream.
  402. * @tparam _Traits Traits for character type, defaults to
  403. * char_traits<_CharT>.
  404. *
  405. * This class supports reading from named files, using the inherited
  406. * functions from std::basic_istream. To control the associated
  407. * sequence, an instance of std::basic_filebuf is used, which this page
  408. * refers to as @c sb.
  409. */
  410. template<typename _CharT, typename _Traits>
  411. class basic_ifstream : public basic_istream<_CharT, _Traits>
  412. {
  413. public:
  414. // Types:
  415. typedef _CharT char_type;
  416. typedef _Traits traits_type;
  417. typedef typename traits_type::int_type int_type;
  418. typedef typename traits_type::pos_type pos_type;
  419. typedef typename traits_type::off_type off_type;
  420. // Non-standard types:
  421. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  422. typedef basic_istream<char_type, traits_type> __istream_type;
  423. private:
  424. __filebuf_type _M_filebuf;
  425. public:
  426. // Constructors/Destructors:
  427. /**
  428. * @brief Default constructor.
  429. *
  430. * Initializes @c sb using its default constructor, and passes
  431. * @c &sb to the base class initializer. Does not open any files
  432. * (you haven't given it a filename to open).
  433. */
  434. basic_ifstream() : __istream_type(), _M_filebuf()
  435. { this->init(&_M_filebuf); }
  436. /**
  437. * @brief Create an input file stream.
  438. * @param __s Null terminated string specifying the filename.
  439. * @param __mode Open file in specified mode (see std::ios_base).
  440. *
  441. * @c ios_base::in is automatically included in @a __mode.
  442. */
  443. explicit
  444. basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
  445. : __istream_type(), _M_filebuf()
  446. {
  447. this->init(&_M_filebuf);
  448. this->open(__s, __mode);
  449. }
  450. #if __cplusplus >= 201103L
  451. /**
  452. * @brief Create an input file stream.
  453. * @param __s std::string specifying the filename.
  454. * @param __mode Open file in specified mode (see std::ios_base).
  455. *
  456. * @c ios_base::in is automatically included in @a __mode.
  457. */
  458. explicit
  459. basic_ifstream(const std::string& __s,
  460. ios_base::openmode __mode = ios_base::in)
  461. : __istream_type(), _M_filebuf()
  462. {
  463. this->init(&_M_filebuf);
  464. this->open(__s, __mode);
  465. }
  466. #if __cplusplus >= 201703L
  467. /**
  468. * @param Create an input file stream.
  469. * @param __s filesystem::path specifying the filename.
  470. * @param __mode Open file in specified mode (see std::ios_base).
  471. *
  472. * @c ios_base::in is automatically included in @a __mode.
  473. */
  474. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  475. basic_ifstream(const _Path& __s,
  476. ios_base::openmode __mode = ios_base::in)
  477. : basic_ifstream(__s.c_str(), __mode)
  478. { }
  479. #endif // C++17
  480. basic_ifstream(const basic_ifstream&) = delete;
  481. basic_ifstream(basic_ifstream&& __rhs)
  482. : __istream_type(std::move(__rhs)),
  483. _M_filebuf(std::move(__rhs._M_filebuf))
  484. { __istream_type::set_rdbuf(&_M_filebuf); }
  485. #endif // C++11
  486. /**
  487. * @brief The destructor does nothing.
  488. *
  489. * The file is closed by the filebuf object, not the formatting
  490. * stream.
  491. */
  492. ~basic_ifstream()
  493. { }
  494. #if __cplusplus >= 201103L
  495. // 27.8.3.2 Assign and swap:
  496. basic_ifstream&
  497. operator=(const basic_ifstream&) = delete;
  498. basic_ifstream&
  499. operator=(basic_ifstream&& __rhs)
  500. {
  501. __istream_type::operator=(std::move(__rhs));
  502. _M_filebuf = std::move(__rhs._M_filebuf);
  503. return *this;
  504. }
  505. void
  506. swap(basic_ifstream& __rhs)
  507. {
  508. __istream_type::swap(__rhs);
  509. _M_filebuf.swap(__rhs._M_filebuf);
  510. }
  511. #endif
  512. // Members:
  513. /**
  514. * @brief Accessing the underlying buffer.
  515. * @return The current basic_filebuf buffer.
  516. *
  517. * This hides both signatures of std::basic_ios::rdbuf().
  518. */
  519. __filebuf_type*
  520. rdbuf() const
  521. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  522. /**
  523. * @brief Wrapper to test for an open file.
  524. * @return @c rdbuf()->is_open()
  525. */
  526. bool
  527. is_open()
  528. { return _M_filebuf.is_open(); }
  529. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  530. // 365. Lack of const-qualification in clause 27
  531. bool
  532. is_open() const
  533. { return _M_filebuf.is_open(); }
  534. /**
  535. * @brief Opens an external file.
  536. * @param __s The name of the file.
  537. * @param __mode The open mode flags.
  538. *
  539. * Calls @c std::basic_filebuf::open(s,__mode|in). If that function
  540. * fails, @c failbit is set in the stream's error state.
  541. */
  542. void
  543. open(const char* __s, ios_base::openmode __mode = ios_base::in)
  544. {
  545. if (!_M_filebuf.open(__s, __mode | ios_base::in))
  546. this->setstate(ios_base::failbit);
  547. else
  548. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  549. // 409. Closing an fstream should clear error state
  550. this->clear();
  551. }
  552. #if __cplusplus >= 201103L
  553. /**
  554. * @brief Opens an external file.
  555. * @param __s The name of the file.
  556. * @param __mode The open mode flags.
  557. *
  558. * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
  559. * fails, @c failbit is set in the stream's error state.
  560. */
  561. void
  562. open(const std::string& __s, ios_base::openmode __mode = ios_base::in)
  563. {
  564. if (!_M_filebuf.open(__s, __mode | ios_base::in))
  565. this->setstate(ios_base::failbit);
  566. else
  567. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  568. // 409. Closing an fstream should clear error state
  569. this->clear();
  570. }
  571. #if __cplusplus >= 201703L
  572. /**
  573. * @brief Opens an external file.
  574. * @param __s The name of the file, as a filesystem::path.
  575. * @param __mode The open mode flags.
  576. *
  577. * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
  578. * fails, @c failbit is set in the stream's error state.
  579. */
  580. template<typename _Path>
  581. _If_fs_path<_Path, void>
  582. open(const _Path& __s, ios_base::openmode __mode = ios_base::in)
  583. { open(__s.c_str(), __mode); }
  584. #endif // C++17
  585. #endif // C++11
  586. /**
  587. * @brief Close the file.
  588. *
  589. * Calls @c std::basic_filebuf::close(). If that function
  590. * fails, @c failbit is set in the stream's error state.
  591. */
  592. void
  593. close()
  594. {
  595. if (!_M_filebuf.close())
  596. this->setstate(ios_base::failbit);
  597. }
  598. };
  599. // [27.8.1.8] Template class basic_ofstream
  600. /**
  601. * @brief Controlling output for files.
  602. * @ingroup io
  603. *
  604. * @tparam _CharT Type of character stream.
  605. * @tparam _Traits Traits for character type, defaults to
  606. * char_traits<_CharT>.
  607. *
  608. * This class supports reading from named files, using the inherited
  609. * functions from std::basic_ostream. To control the associated
  610. * sequence, an instance of std::basic_filebuf is used, which this page
  611. * refers to as @c sb.
  612. */
  613. template<typename _CharT, typename _Traits>
  614. class basic_ofstream : public basic_ostream<_CharT,_Traits>
  615. {
  616. public:
  617. // Types:
  618. typedef _CharT char_type;
  619. typedef _Traits traits_type;
  620. typedef typename traits_type::int_type int_type;
  621. typedef typename traits_type::pos_type pos_type;
  622. typedef typename traits_type::off_type off_type;
  623. // Non-standard types:
  624. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  625. typedef basic_ostream<char_type, traits_type> __ostream_type;
  626. private:
  627. __filebuf_type _M_filebuf;
  628. public:
  629. // Constructors:
  630. /**
  631. * @brief Default constructor.
  632. *
  633. * Initializes @c sb using its default constructor, and passes
  634. * @c &sb to the base class initializer. Does not open any files
  635. * (you haven't given it a filename to open).
  636. */
  637. basic_ofstream(): __ostream_type(), _M_filebuf()
  638. { this->init(&_M_filebuf); }
  639. /**
  640. * @brief Create an output file stream.
  641. * @param __s Null terminated string specifying the filename.
  642. * @param __mode Open file in specified mode (see std::ios_base).
  643. *
  644. * @c ios_base::out is automatically included in @a __mode.
  645. */
  646. explicit
  647. basic_ofstream(const char* __s,
  648. ios_base::openmode __mode = ios_base::out)
  649. : __ostream_type(), _M_filebuf()
  650. {
  651. this->init(&_M_filebuf);
  652. this->open(__s, __mode);
  653. }
  654. #if __cplusplus >= 201103L
  655. /**
  656. * @brief Create an output file stream.
  657. * @param __s std::string specifying the filename.
  658. * @param __mode Open file in specified mode (see std::ios_base).
  659. *
  660. * @c ios_base::out is automatically included in @a __mode.
  661. */
  662. explicit
  663. basic_ofstream(const std::string& __s,
  664. ios_base::openmode __mode = ios_base::out)
  665. : __ostream_type(), _M_filebuf()
  666. {
  667. this->init(&_M_filebuf);
  668. this->open(__s, __mode);
  669. }
  670. #if __cplusplus >= 201703L
  671. /**
  672. * @param Create an output file stream.
  673. * @param __s filesystem::path specifying the filename.
  674. * @param __mode Open file in specified mode (see std::ios_base).
  675. *
  676. * @c ios_base::out is automatically included in @a __mode.
  677. */
  678. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  679. basic_ofstream(const _Path& __s,
  680. ios_base::openmode __mode = ios_base::out)
  681. : basic_ofstream(__s.c_str(), __mode)
  682. { }
  683. #endif // C++17
  684. basic_ofstream(const basic_ofstream&) = delete;
  685. basic_ofstream(basic_ofstream&& __rhs)
  686. : __ostream_type(std::move(__rhs)),
  687. _M_filebuf(std::move(__rhs._M_filebuf))
  688. { __ostream_type::set_rdbuf(&_M_filebuf); }
  689. #endif
  690. /**
  691. * @brief The destructor does nothing.
  692. *
  693. * The file is closed by the filebuf object, not the formatting
  694. * stream.
  695. */
  696. ~basic_ofstream()
  697. { }
  698. #if __cplusplus >= 201103L
  699. // 27.8.3.2 Assign and swap:
  700. basic_ofstream&
  701. operator=(const basic_ofstream&) = delete;
  702. basic_ofstream&
  703. operator=(basic_ofstream&& __rhs)
  704. {
  705. __ostream_type::operator=(std::move(__rhs));
  706. _M_filebuf = std::move(__rhs._M_filebuf);
  707. return *this;
  708. }
  709. void
  710. swap(basic_ofstream& __rhs)
  711. {
  712. __ostream_type::swap(__rhs);
  713. _M_filebuf.swap(__rhs._M_filebuf);
  714. }
  715. #endif
  716. // Members:
  717. /**
  718. * @brief Accessing the underlying buffer.
  719. * @return The current basic_filebuf buffer.
  720. *
  721. * This hides both signatures of std::basic_ios::rdbuf().
  722. */
  723. __filebuf_type*
  724. rdbuf() const
  725. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  726. /**
  727. * @brief Wrapper to test for an open file.
  728. * @return @c rdbuf()->is_open()
  729. */
  730. bool
  731. is_open()
  732. { return _M_filebuf.is_open(); }
  733. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  734. // 365. Lack of const-qualification in clause 27
  735. bool
  736. is_open() const
  737. { return _M_filebuf.is_open(); }
  738. /**
  739. * @brief Opens an external file.
  740. * @param __s The name of the file.
  741. * @param __mode The open mode flags.
  742. *
  743. * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
  744. * function fails, @c failbit is set in the stream's error state.
  745. */
  746. void
  747. open(const char* __s, ios_base::openmode __mode = ios_base::out)
  748. {
  749. if (!_M_filebuf.open(__s, __mode | ios_base::out))
  750. this->setstate(ios_base::failbit);
  751. else
  752. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  753. // 409. Closing an fstream should clear error state
  754. this->clear();
  755. }
  756. #if __cplusplus >= 201103L
  757. /**
  758. * @brief Opens an external file.
  759. * @param __s The name of the file.
  760. * @param __mode The open mode flags.
  761. *
  762. * Calls @c std::basic_filebuf::open(s,mode|out). If that
  763. * function fails, @c failbit is set in the stream's error state.
  764. */
  765. void
  766. open(const std::string& __s, ios_base::openmode __mode = ios_base::out)
  767. {
  768. if (!_M_filebuf.open(__s, __mode | ios_base::out))
  769. this->setstate(ios_base::failbit);
  770. else
  771. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  772. // 409. Closing an fstream should clear error state
  773. this->clear();
  774. }
  775. #if __cplusplus >= 201703L
  776. /**
  777. * @brief Opens an external file.
  778. * @param __s The name of the file, as a filesystem::path.
  779. * @param __mode The open mode flags.
  780. *
  781. * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
  782. * function fails, @c failbit is set in the stream's error state.
  783. */
  784. template<typename _Path>
  785. _If_fs_path<_Path, void>
  786. open(const _Path& __s, ios_base::openmode __mode = ios_base::out)
  787. { open(__s.c_str(), __mode); }
  788. #endif // C++17
  789. #endif // C++11
  790. /**
  791. * @brief Close the file.
  792. *
  793. * Calls @c std::basic_filebuf::close(). If that function
  794. * fails, @c failbit is set in the stream's error state.
  795. */
  796. void
  797. close()
  798. {
  799. if (!_M_filebuf.close())
  800. this->setstate(ios_base::failbit);
  801. }
  802. };
  803. // [27.8.1.11] Template class basic_fstream
  804. /**
  805. * @brief Controlling input and output for files.
  806. * @ingroup io
  807. *
  808. * @tparam _CharT Type of character stream.
  809. * @tparam _Traits Traits for character type, defaults to
  810. * char_traits<_CharT>.
  811. *
  812. * This class supports reading from and writing to named files, using
  813. * the inherited functions from std::basic_iostream. To control the
  814. * associated sequence, an instance of std::basic_filebuf is used, which
  815. * this page refers to as @c sb.
  816. */
  817. template<typename _CharT, typename _Traits>
  818. class basic_fstream : public basic_iostream<_CharT, _Traits>
  819. {
  820. public:
  821. // Types:
  822. typedef _CharT char_type;
  823. typedef _Traits traits_type;
  824. typedef typename traits_type::int_type int_type;
  825. typedef typename traits_type::pos_type pos_type;
  826. typedef typename traits_type::off_type off_type;
  827. // Non-standard types:
  828. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  829. typedef basic_ios<char_type, traits_type> __ios_type;
  830. typedef basic_iostream<char_type, traits_type> __iostream_type;
  831. private:
  832. __filebuf_type _M_filebuf;
  833. public:
  834. // Constructors/destructor:
  835. /**
  836. * @brief Default constructor.
  837. *
  838. * Initializes @c sb using its default constructor, and passes
  839. * @c &sb to the base class initializer. Does not open any files
  840. * (you haven't given it a filename to open).
  841. */
  842. basic_fstream()
  843. : __iostream_type(), _M_filebuf()
  844. { this->init(&_M_filebuf); }
  845. /**
  846. * @brief Create an input/output file stream.
  847. * @param __s Null terminated string specifying the filename.
  848. * @param __mode Open file in specified mode (see std::ios_base).
  849. */
  850. explicit
  851. basic_fstream(const char* __s,
  852. ios_base::openmode __mode = ios_base::in | ios_base::out)
  853. : __iostream_type(0), _M_filebuf()
  854. {
  855. this->init(&_M_filebuf);
  856. this->open(__s, __mode);
  857. }
  858. #if __cplusplus >= 201103L
  859. /**
  860. * @brief Create an input/output file stream.
  861. * @param __s Null terminated string specifying the filename.
  862. * @param __mode Open file in specified mode (see std::ios_base).
  863. */
  864. explicit
  865. basic_fstream(const std::string& __s,
  866. ios_base::openmode __mode = ios_base::in | ios_base::out)
  867. : __iostream_type(0), _M_filebuf()
  868. {
  869. this->init(&_M_filebuf);
  870. this->open(__s, __mode);
  871. }
  872. #if __cplusplus >= 201703L
  873. /**
  874. * @param Create an input/output file stream.
  875. * @param __s filesystem::path specifying the filename.
  876. * @param __mode Open file in specified mode (see std::ios_base).
  877. */
  878. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  879. basic_fstream(const _Path& __s,
  880. ios_base::openmode __mode = ios_base::in | ios_base::out)
  881. : basic_fstream(__s.c_str(), __mode)
  882. { }
  883. #endif // C++17
  884. basic_fstream(const basic_fstream&) = delete;
  885. basic_fstream(basic_fstream&& __rhs)
  886. : __iostream_type(std::move(__rhs)),
  887. _M_filebuf(std::move(__rhs._M_filebuf))
  888. { __iostream_type::set_rdbuf(&_M_filebuf); }
  889. #endif
  890. /**
  891. * @brief The destructor does nothing.
  892. *
  893. * The file is closed by the filebuf object, not the formatting
  894. * stream.
  895. */
  896. ~basic_fstream()
  897. { }
  898. #if __cplusplus >= 201103L
  899. // 27.8.3.2 Assign and swap:
  900. basic_fstream&
  901. operator=(const basic_fstream&) = delete;
  902. basic_fstream&
  903. operator=(basic_fstream&& __rhs)
  904. {
  905. __iostream_type::operator=(std::move(__rhs));
  906. _M_filebuf = std::move(__rhs._M_filebuf);
  907. return *this;
  908. }
  909. void
  910. swap(basic_fstream& __rhs)
  911. {
  912. __iostream_type::swap(__rhs);
  913. _M_filebuf.swap(__rhs._M_filebuf);
  914. }
  915. #endif
  916. // Members:
  917. /**
  918. * @brief Accessing the underlying buffer.
  919. * @return The current basic_filebuf buffer.
  920. *
  921. * This hides both signatures of std::basic_ios::rdbuf().
  922. */
  923. __filebuf_type*
  924. rdbuf() const
  925. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  926. /**
  927. * @brief Wrapper to test for an open file.
  928. * @return @c rdbuf()->is_open()
  929. */
  930. bool
  931. is_open()
  932. { return _M_filebuf.is_open(); }
  933. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  934. // 365. Lack of const-qualification in clause 27
  935. bool
  936. is_open() const
  937. { return _M_filebuf.is_open(); }
  938. /**
  939. * @brief Opens an external file.
  940. * @param __s The name of the file.
  941. * @param __mode The open mode flags.
  942. *
  943. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  944. * function fails, @c failbit is set in the stream's error state.
  945. */
  946. void
  947. open(const char* __s,
  948. ios_base::openmode __mode = ios_base::in | ios_base::out)
  949. {
  950. if (!_M_filebuf.open(__s, __mode))
  951. this->setstate(ios_base::failbit);
  952. else
  953. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  954. // 409. Closing an fstream should clear error state
  955. this->clear();
  956. }
  957. #if __cplusplus >= 201103L
  958. /**
  959. * @brief Opens an external file.
  960. * @param __s The name of the file.
  961. * @param __mode The open mode flags.
  962. *
  963. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  964. * function fails, @c failbit is set in the stream's error state.
  965. */
  966. void
  967. open(const std::string& __s,
  968. ios_base::openmode __mode = ios_base::in | ios_base::out)
  969. {
  970. if (!_M_filebuf.open(__s, __mode))
  971. this->setstate(ios_base::failbit);
  972. else
  973. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  974. // 409. Closing an fstream should clear error state
  975. this->clear();
  976. }
  977. #if __cplusplus >= 201703L
  978. /**
  979. * @brief Opens an external file.
  980. * @param __s The name of the file, as a filesystem::path.
  981. * @param __mode The open mode flags.
  982. *
  983. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  984. * function fails, @c failbit is set in the stream's error state.
  985. */
  986. template<typename _Path>
  987. _If_fs_path<_Path, void>
  988. open(const _Path& __s,
  989. ios_base::openmode __mode = ios_base::in | ios_base::out)
  990. { open(__s.c_str(), __mode); }
  991. #endif // C++17
  992. #endif // C++11
  993. /**
  994. * @brief Close the file.
  995. *
  996. * Calls @c std::basic_filebuf::close(). If that function
  997. * fails, @c failbit is set in the stream's error state.
  998. */
  999. void
  1000. close()
  1001. {
  1002. if (!_M_filebuf.close())
  1003. this->setstate(ios_base::failbit);
  1004. }
  1005. };
  1006. #if __cplusplus >= 201103L
  1007. /// Swap specialization for filebufs.
  1008. template <class _CharT, class _Traits>
  1009. inline void
  1010. swap(basic_filebuf<_CharT, _Traits>& __x,
  1011. basic_filebuf<_CharT, _Traits>& __y)
  1012. { __x.swap(__y); }
  1013. /// Swap specialization for ifstreams.
  1014. template <class _CharT, class _Traits>
  1015. inline void
  1016. swap(basic_ifstream<_CharT, _Traits>& __x,
  1017. basic_ifstream<_CharT, _Traits>& __y)
  1018. { __x.swap(__y); }
  1019. /// Swap specialization for ofstreams.
  1020. template <class _CharT, class _Traits>
  1021. inline void
  1022. swap(basic_ofstream<_CharT, _Traits>& __x,
  1023. basic_ofstream<_CharT, _Traits>& __y)
  1024. { __x.swap(__y); }
  1025. /// Swap specialization for fstreams.
  1026. template <class _CharT, class _Traits>
  1027. inline void
  1028. swap(basic_fstream<_CharT, _Traits>& __x,
  1029. basic_fstream<_CharT, _Traits>& __y)
  1030. { __x.swap(__y); }
  1031. #endif
  1032. _GLIBCXX_END_NAMESPACE_VERSION
  1033. } // namespace
  1034. #include <bits/fstream.tcc>
  1035. #endif /* _GLIBCXX_FSTREAM */