No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

1296 líneas
40KB

  1. // File based streams -*- C++ -*-
  2. // Copyright (C) 1997-2020 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. {
  211. __try
  212. { this->close(); }
  213. __catch(...)
  214. { }
  215. }
  216. #if __cplusplus >= 201103L
  217. basic_filebuf& operator=(const basic_filebuf&) = delete;
  218. basic_filebuf& operator=(basic_filebuf&&);
  219. void swap(basic_filebuf&);
  220. #endif
  221. // Members:
  222. /**
  223. * @brief Returns true if the external file is open.
  224. */
  225. bool
  226. is_open() const throw()
  227. { return _M_file.is_open(); }
  228. /**
  229. * @brief Opens an external file.
  230. * @param __s The name of the file.
  231. * @param __mode The open mode flags.
  232. * @return @c this on success, NULL on failure
  233. *
  234. * If a file is already open, this function immediately fails.
  235. * Otherwise it tries to open the file named @a __s using the flags
  236. * given in @a __mode.
  237. *
  238. * Table 92, adapted here, gives the relation between openmode
  239. * combinations and the equivalent @c fopen() flags.
  240. * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
  241. * and binary|in|app per DR 596)
  242. * <pre>
  243. * +---------------------------------------------------------+
  244. * | ios_base Flag combination stdio equivalent |
  245. * |binary in out trunc app |
  246. * +---------------------------------------------------------+
  247. * | + w |
  248. * | + + a |
  249. * | + a |
  250. * | + + w |
  251. * | + r |
  252. * | + + r+ |
  253. * | + + + w+ |
  254. * | + + + a+ |
  255. * | + + a+ |
  256. * +---------------------------------------------------------+
  257. * | + + wb |
  258. * | + + + ab |
  259. * | + + ab |
  260. * | + + + wb |
  261. * | + + rb |
  262. * | + + + r+b |
  263. * | + + + + w+b |
  264. * | + + + + a+b |
  265. * | + + + a+b |
  266. * +---------------------------------------------------------+
  267. * </pre>
  268. */
  269. __filebuf_type*
  270. open(const char* __s, ios_base::openmode __mode);
  271. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  272. /**
  273. * @brief Opens an external file.
  274. * @param __s The name of the file, as a wide character string.
  275. * @param __mode The open mode flags.
  276. * @return @c this on success, NULL on failure
  277. */
  278. __filebuf_type*
  279. open(const wchar_t* __s, ios_base::openmode __mode);
  280. #endif
  281. #if __cplusplus >= 201103L
  282. /**
  283. * @brief Opens an external file.
  284. * @param __s The name of the file.
  285. * @param __mode The open mode flags.
  286. * @return @c this on success, NULL on failure
  287. */
  288. __filebuf_type*
  289. open(const std::string& __s, ios_base::openmode __mode)
  290. { return open(__s.c_str(), __mode); }
  291. #if __cplusplus >= 201703L
  292. /**
  293. * @brief Opens an external file.
  294. * @param __s The name of the file, as a filesystem::path.
  295. * @param __mode The open mode flags.
  296. * @return @c this on success, NULL on failure
  297. */
  298. template<typename _Path>
  299. _If_fs_path<_Path, __filebuf_type*>
  300. open(const _Path& __s, ios_base::openmode __mode)
  301. { return open(__s.c_str(), __mode); }
  302. #endif // C++17
  303. #endif // C++11
  304. /**
  305. * @brief Closes the currently associated file.
  306. * @return @c this on success, NULL on failure
  307. *
  308. * If no file is currently open, this function immediately fails.
  309. *
  310. * If a <em>put buffer area</em> exists, @c overflow(eof) is
  311. * called to flush all the characters. The file is then
  312. * closed.
  313. *
  314. * If any operations fail, this function also fails.
  315. */
  316. __filebuf_type*
  317. close();
  318. protected:
  319. void
  320. _M_allocate_internal_buffer();
  321. void
  322. _M_destroy_internal_buffer() throw();
  323. // [27.8.1.4] overridden virtual functions
  324. virtual streamsize
  325. showmanyc();
  326. // Stroustrup, 1998, p. 628
  327. // underflow() and uflow() functions are called to get the next
  328. // character from the real input source when the buffer is empty.
  329. // Buffered input uses underflow()
  330. virtual int_type
  331. underflow();
  332. virtual int_type
  333. pbackfail(int_type __c = _Traits::eof());
  334. // Stroustrup, 1998, p 648
  335. // The overflow() function is called to transfer characters to the
  336. // real output destination when the buffer is full. A call to
  337. // overflow(c) outputs the contents of the buffer plus the
  338. // character c.
  339. // 27.5.2.4.5
  340. // Consume some sequence of the characters in the pending sequence.
  341. virtual int_type
  342. overflow(int_type __c = _Traits::eof());
  343. // Convert internal byte sequence to external, char-based
  344. // sequence via codecvt.
  345. bool
  346. _M_convert_to_external(char_type*, streamsize);
  347. /**
  348. * @brief Manipulates the buffer.
  349. * @param __s Pointer to a buffer area.
  350. * @param __n Size of @a __s.
  351. * @return @c this
  352. *
  353. * If no file has been opened, and both @a __s and @a __n are zero, then
  354. * the stream becomes unbuffered. Otherwise, @c __s is used as a
  355. * buffer; see
  356. * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
  357. * for more.
  358. */
  359. virtual __streambuf_type*
  360. setbuf(char_type* __s, streamsize __n);
  361. virtual pos_type
  362. seekoff(off_type __off, ios_base::seekdir __way,
  363. ios_base::openmode __mode = ios_base::in | ios_base::out);
  364. virtual pos_type
  365. seekpos(pos_type __pos,
  366. ios_base::openmode __mode = ios_base::in | ios_base::out);
  367. // Common code for seekoff, seekpos, and overflow
  368. pos_type
  369. _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
  370. int
  371. _M_get_ext_pos(__state_type &__state);
  372. virtual int
  373. sync();
  374. virtual void
  375. imbue(const locale& __loc);
  376. virtual streamsize
  377. xsgetn(char_type* __s, streamsize __n);
  378. virtual streamsize
  379. xsputn(const char_type* __s, streamsize __n);
  380. // Flushes output buffer, then writes unshift sequence.
  381. bool
  382. _M_terminate_output();
  383. /**
  384. * This function sets the pointers of the internal buffer, both get
  385. * and put areas. Typically:
  386. *
  387. * __off == egptr() - eback() upon underflow/uflow (@b read mode);
  388. * __off == 0 upon overflow (@b write mode);
  389. * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode).
  390. *
  391. * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
  392. * reflects the actual allocated memory and the last cell is reserved
  393. * for the overflow char of a full put area.
  394. */
  395. void
  396. _M_set_buffer(streamsize __off)
  397. {
  398. const bool __testin = _M_mode & ios_base::in;
  399. const bool __testout = (_M_mode & ios_base::out
  400. || _M_mode & ios_base::app);
  401. if (__testin && __off > 0)
  402. this->setg(_M_buf, _M_buf, _M_buf + __off);
  403. else
  404. this->setg(_M_buf, _M_buf, _M_buf);
  405. if (__testout && __off == 0 && _M_buf_size > 1 )
  406. this->setp(_M_buf, _M_buf + _M_buf_size - 1);
  407. else
  408. this->setp(0, 0);
  409. }
  410. };
  411. // [27.8.1.5] Template class basic_ifstream
  412. /**
  413. * @brief Controlling input for files.
  414. * @ingroup io
  415. *
  416. * @tparam _CharT Type of character stream.
  417. * @tparam _Traits Traits for character type, defaults to
  418. * char_traits<_CharT>.
  419. *
  420. * This class supports reading from named files, using the inherited
  421. * functions from std::basic_istream. To control the associated
  422. * sequence, an instance of std::basic_filebuf is used, which this page
  423. * refers to as @c sb.
  424. */
  425. template<typename _CharT, typename _Traits>
  426. class basic_ifstream : public basic_istream<_CharT, _Traits>
  427. {
  428. public:
  429. // Types:
  430. typedef _CharT char_type;
  431. typedef _Traits traits_type;
  432. typedef typename traits_type::int_type int_type;
  433. typedef typename traits_type::pos_type pos_type;
  434. typedef typename traits_type::off_type off_type;
  435. // Non-standard types:
  436. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  437. typedef basic_istream<char_type, traits_type> __istream_type;
  438. private:
  439. __filebuf_type _M_filebuf;
  440. public:
  441. // Constructors/Destructors:
  442. /**
  443. * @brief Default constructor.
  444. *
  445. * Initializes @c sb using its default constructor, and passes
  446. * @c &sb to the base class initializer. Does not open any files
  447. * (you haven't given it a filename to open).
  448. */
  449. basic_ifstream() : __istream_type(), _M_filebuf()
  450. { this->init(&_M_filebuf); }
  451. /**
  452. * @brief Create an input file stream.
  453. * @param __s Null terminated 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 char* __s, ios_base::openmode __mode = ios_base::in)
  460. : __istream_type(), _M_filebuf()
  461. {
  462. this->init(&_M_filebuf);
  463. this->open(__s, __mode);
  464. }
  465. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  466. /**
  467. * @param Create an input file stream.
  468. * @param __s Wide string specifying the filename.
  469. * @param __mode Open file in specified mode (see std::ios_base).
  470. *
  471. * @c ios_base::in is automatically included in @a __mode.
  472. */
  473. basic_ifstream(const wchar_t* __s,
  474. ios_base::openmode __mode = ios_base::in)
  475. : __istream_type(), _M_filebuf()
  476. {
  477. this->init(&_M_filebuf);
  478. this->open(__s, __mode);
  479. }
  480. #endif
  481. #if __cplusplus >= 201103L
  482. /**
  483. * @brief Create an input file stream.
  484. * @param __s std::string specifying the filename.
  485. * @param __mode Open file in specified mode (see std::ios_base).
  486. *
  487. * @c ios_base::in is automatically included in @a __mode.
  488. */
  489. explicit
  490. basic_ifstream(const std::string& __s,
  491. ios_base::openmode __mode = ios_base::in)
  492. : __istream_type(), _M_filebuf()
  493. {
  494. this->init(&_M_filebuf);
  495. this->open(__s, __mode);
  496. }
  497. #if __cplusplus >= 201703L
  498. /**
  499. * @brief Create an input file stream.
  500. * @param __s filesystem::path specifying the filename.
  501. * @param __mode Open file in specified mode (see std::ios_base).
  502. *
  503. * @c ios_base::in is automatically included in @a __mode.
  504. */
  505. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  506. basic_ifstream(const _Path& __s,
  507. ios_base::openmode __mode = ios_base::in)
  508. : basic_ifstream(__s.c_str(), __mode)
  509. { }
  510. #endif // C++17
  511. basic_ifstream(const basic_ifstream&) = delete;
  512. basic_ifstream(basic_ifstream&& __rhs)
  513. : __istream_type(std::move(__rhs)),
  514. _M_filebuf(std::move(__rhs._M_filebuf))
  515. { __istream_type::set_rdbuf(&_M_filebuf); }
  516. #endif // C++11
  517. /**
  518. * @brief The destructor does nothing.
  519. *
  520. * The file is closed by the filebuf object, not the formatting
  521. * stream.
  522. */
  523. ~basic_ifstream()
  524. { }
  525. #if __cplusplus >= 201103L
  526. // 27.8.3.2 Assign and swap:
  527. basic_ifstream&
  528. operator=(const basic_ifstream&) = delete;
  529. basic_ifstream&
  530. operator=(basic_ifstream&& __rhs)
  531. {
  532. __istream_type::operator=(std::move(__rhs));
  533. _M_filebuf = std::move(__rhs._M_filebuf);
  534. return *this;
  535. }
  536. void
  537. swap(basic_ifstream& __rhs)
  538. {
  539. __istream_type::swap(__rhs);
  540. _M_filebuf.swap(__rhs._M_filebuf);
  541. }
  542. #endif
  543. // Members:
  544. /**
  545. * @brief Accessing the underlying buffer.
  546. * @return The current basic_filebuf buffer.
  547. *
  548. * This hides both signatures of std::basic_ios::rdbuf().
  549. */
  550. __filebuf_type*
  551. rdbuf() const
  552. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  553. /**
  554. * @brief Wrapper to test for an open file.
  555. * @return @c rdbuf()->is_open()
  556. */
  557. bool
  558. is_open()
  559. { return _M_filebuf.is_open(); }
  560. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  561. // 365. Lack of const-qualification in clause 27
  562. bool
  563. is_open() const
  564. { return _M_filebuf.is_open(); }
  565. /**
  566. * @brief Opens an external file.
  567. * @param __s The name of the file.
  568. * @param __mode The open mode flags.
  569. *
  570. * Calls @c std::basic_filebuf::open(s,__mode|in). If that function
  571. * fails, @c failbit is set in the stream's error state.
  572. */
  573. void
  574. open(const char* __s, ios_base::openmode __mode = ios_base::in)
  575. {
  576. if (!_M_filebuf.open(__s, __mode | ios_base::in))
  577. this->setstate(ios_base::failbit);
  578. else
  579. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  580. // 409. Closing an fstream should clear error state
  581. this->clear();
  582. }
  583. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  584. /**
  585. * @brief Opens an external file.
  586. * @param __s The name of the file, as a wide character string.
  587. * @param __mode The open mode flags.
  588. *
  589. * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
  590. * fails, @c failbit is set in the stream's error state.
  591. */
  592. void
  593. open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in)
  594. {
  595. if (!_M_filebuf.open(__s, __mode | ios_base::in))
  596. this->setstate(ios_base::failbit);
  597. else
  598. this->clear();
  599. }
  600. #endif
  601. #if __cplusplus >= 201103L
  602. /**
  603. * @brief Opens an external file.
  604. * @param __s The name of the file.
  605. * @param __mode The open mode flags.
  606. *
  607. * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
  608. * fails, @c failbit is set in the stream's error state.
  609. */
  610. void
  611. open(const std::string& __s, ios_base::openmode __mode = ios_base::in)
  612. {
  613. if (!_M_filebuf.open(__s, __mode | ios_base::in))
  614. this->setstate(ios_base::failbit);
  615. else
  616. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  617. // 409. Closing an fstream should clear error state
  618. this->clear();
  619. }
  620. #if __cplusplus >= 201703L
  621. /**
  622. * @brief Opens an external file.
  623. * @param __s The name of the file, as a filesystem::path.
  624. * @param __mode The open mode flags.
  625. *
  626. * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
  627. * fails, @c failbit is set in the stream's error state.
  628. */
  629. template<typename _Path>
  630. _If_fs_path<_Path, void>
  631. open(const _Path& __s, ios_base::openmode __mode = ios_base::in)
  632. { open(__s.c_str(), __mode); }
  633. #endif // C++17
  634. #endif // C++11
  635. /**
  636. * @brief Close the file.
  637. *
  638. * Calls @c std::basic_filebuf::close(). If that function
  639. * fails, @c failbit is set in the stream's error state.
  640. */
  641. void
  642. close()
  643. {
  644. if (!_M_filebuf.close())
  645. this->setstate(ios_base::failbit);
  646. }
  647. };
  648. // [27.8.1.8] Template class basic_ofstream
  649. /**
  650. * @brief Controlling output for files.
  651. * @ingroup io
  652. *
  653. * @tparam _CharT Type of character stream.
  654. * @tparam _Traits Traits for character type, defaults to
  655. * char_traits<_CharT>.
  656. *
  657. * This class supports reading from named files, using the inherited
  658. * functions from std::basic_ostream. To control the associated
  659. * sequence, an instance of std::basic_filebuf is used, which this page
  660. * refers to as @c sb.
  661. */
  662. template<typename _CharT, typename _Traits>
  663. class basic_ofstream : public basic_ostream<_CharT,_Traits>
  664. {
  665. public:
  666. // Types:
  667. typedef _CharT char_type;
  668. typedef _Traits traits_type;
  669. typedef typename traits_type::int_type int_type;
  670. typedef typename traits_type::pos_type pos_type;
  671. typedef typename traits_type::off_type off_type;
  672. // Non-standard types:
  673. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  674. typedef basic_ostream<char_type, traits_type> __ostream_type;
  675. private:
  676. __filebuf_type _M_filebuf;
  677. public:
  678. // Constructors:
  679. /**
  680. * @brief Default constructor.
  681. *
  682. * Initializes @c sb using its default constructor, and passes
  683. * @c &sb to the base class initializer. Does not open any files
  684. * (you haven't given it a filename to open).
  685. */
  686. basic_ofstream(): __ostream_type(), _M_filebuf()
  687. { this->init(&_M_filebuf); }
  688. /**
  689. * @brief Create an output file stream.
  690. * @param __s Null terminated string specifying the filename.
  691. * @param __mode Open file in specified mode (see std::ios_base).
  692. *
  693. * @c ios_base::out is automatically included in @a __mode.
  694. */
  695. explicit
  696. basic_ofstream(const char* __s,
  697. ios_base::openmode __mode = ios_base::out)
  698. : __ostream_type(), _M_filebuf()
  699. {
  700. this->init(&_M_filebuf);
  701. this->open(__s, __mode);
  702. }
  703. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  704. /**
  705. * @param Create an output file stream.
  706. * @param __s Wide string specifying the filename.
  707. * @param __mode Open file in specified mode (see std::ios_base).
  708. *
  709. * @c ios_base::out | @c ios_base::trunc is automatically included in
  710. * @a __mode.
  711. */
  712. basic_ofstream(const wchar_t* __s,
  713. ios_base::openmode __mode = ios_base::out|ios_base::trunc)
  714. : __ostream_type(), _M_filebuf()
  715. {
  716. this->init(&_M_filebuf);
  717. this->open(__s, __mode);
  718. }
  719. #endif
  720. #if __cplusplus >= 201103L
  721. /**
  722. * @brief Create an output file stream.
  723. * @param __s std::string specifying the filename.
  724. * @param __mode Open file in specified mode (see std::ios_base).
  725. *
  726. * @c ios_base::out is automatically included in @a __mode.
  727. */
  728. explicit
  729. basic_ofstream(const std::string& __s,
  730. ios_base::openmode __mode = ios_base::out)
  731. : __ostream_type(), _M_filebuf()
  732. {
  733. this->init(&_M_filebuf);
  734. this->open(__s, __mode);
  735. }
  736. #if __cplusplus >= 201703L
  737. /**
  738. * @brief Create an output file stream.
  739. * @param __s filesystem::path specifying the filename.
  740. * @param __mode Open file in specified mode (see std::ios_base).
  741. *
  742. * @c ios_base::out is automatically included in @a __mode.
  743. */
  744. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  745. basic_ofstream(const _Path& __s,
  746. ios_base::openmode __mode = ios_base::out)
  747. : basic_ofstream(__s.c_str(), __mode)
  748. { }
  749. #endif // C++17
  750. basic_ofstream(const basic_ofstream&) = delete;
  751. basic_ofstream(basic_ofstream&& __rhs)
  752. : __ostream_type(std::move(__rhs)),
  753. _M_filebuf(std::move(__rhs._M_filebuf))
  754. { __ostream_type::set_rdbuf(&_M_filebuf); }
  755. #endif
  756. /**
  757. * @brief The destructor does nothing.
  758. *
  759. * The file is closed by the filebuf object, not the formatting
  760. * stream.
  761. */
  762. ~basic_ofstream()
  763. { }
  764. #if __cplusplus >= 201103L
  765. // 27.8.3.2 Assign and swap:
  766. basic_ofstream&
  767. operator=(const basic_ofstream&) = delete;
  768. basic_ofstream&
  769. operator=(basic_ofstream&& __rhs)
  770. {
  771. __ostream_type::operator=(std::move(__rhs));
  772. _M_filebuf = std::move(__rhs._M_filebuf);
  773. return *this;
  774. }
  775. void
  776. swap(basic_ofstream& __rhs)
  777. {
  778. __ostream_type::swap(__rhs);
  779. _M_filebuf.swap(__rhs._M_filebuf);
  780. }
  781. #endif
  782. // Members:
  783. /**
  784. * @brief Accessing the underlying buffer.
  785. * @return The current basic_filebuf buffer.
  786. *
  787. * This hides both signatures of std::basic_ios::rdbuf().
  788. */
  789. __filebuf_type*
  790. rdbuf() const
  791. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  792. /**
  793. * @brief Wrapper to test for an open file.
  794. * @return @c rdbuf()->is_open()
  795. */
  796. bool
  797. is_open()
  798. { return _M_filebuf.is_open(); }
  799. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  800. // 365. Lack of const-qualification in clause 27
  801. bool
  802. is_open() const
  803. { return _M_filebuf.is_open(); }
  804. /**
  805. * @brief Opens an external file.
  806. * @param __s The name of the file.
  807. * @param __mode The open mode flags.
  808. *
  809. * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
  810. * function fails, @c failbit is set in the stream's error state.
  811. */
  812. void
  813. open(const char* __s, ios_base::openmode __mode = ios_base::out)
  814. {
  815. if (!_M_filebuf.open(__s, __mode | ios_base::out))
  816. this->setstate(ios_base::failbit);
  817. else
  818. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  819. // 409. Closing an fstream should clear error state
  820. this->clear();
  821. }
  822. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  823. /**
  824. * @brief Opens an external file.
  825. * @param __s The name of the file.
  826. * @param __mode The open mode flags.
  827. *
  828. * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
  829. * function fails, @c failbit is set in the stream's error state.
  830. */
  831. void
  832. open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out)
  833. {
  834. if (!_M_filebuf.open(__s, __mode | ios_base::out))
  835. this->setstate(ios_base::failbit);
  836. else
  837. this->clear();
  838. }
  839. #endif
  840. #if __cplusplus >= 201103L
  841. /**
  842. * @brief Opens an external file.
  843. * @param __s The name of the file.
  844. * @param __mode The open mode flags.
  845. *
  846. * Calls @c std::basic_filebuf::open(s,mode|out). If that
  847. * function fails, @c failbit is set in the stream's error state.
  848. */
  849. void
  850. open(const std::string& __s, ios_base::openmode __mode = ios_base::out)
  851. {
  852. if (!_M_filebuf.open(__s, __mode | ios_base::out))
  853. this->setstate(ios_base::failbit);
  854. else
  855. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  856. // 409. Closing an fstream should clear error state
  857. this->clear();
  858. }
  859. #if __cplusplus >= 201703L
  860. /**
  861. * @brief Opens an external file.
  862. * @param __s The name of the file, as a filesystem::path.
  863. * @param __mode The open mode flags.
  864. *
  865. * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
  866. * function fails, @c failbit is set in the stream's error state.
  867. */
  868. template<typename _Path>
  869. _If_fs_path<_Path, void>
  870. open(const _Path& __s, ios_base::openmode __mode = ios_base::out)
  871. { open(__s.c_str(), __mode); }
  872. #endif // C++17
  873. #endif // C++11
  874. /**
  875. * @brief Close the file.
  876. *
  877. * Calls @c std::basic_filebuf::close(). If that function
  878. * fails, @c failbit is set in the stream's error state.
  879. */
  880. void
  881. close()
  882. {
  883. if (!_M_filebuf.close())
  884. this->setstate(ios_base::failbit);
  885. }
  886. };
  887. // [27.8.1.11] Template class basic_fstream
  888. /**
  889. * @brief Controlling input and output for files.
  890. * @ingroup io
  891. *
  892. * @tparam _CharT Type of character stream.
  893. * @tparam _Traits Traits for character type, defaults to
  894. * char_traits<_CharT>.
  895. *
  896. * This class supports reading from and writing to named files, using
  897. * the inherited functions from std::basic_iostream. To control the
  898. * associated sequence, an instance of std::basic_filebuf is used, which
  899. * this page refers to as @c sb.
  900. */
  901. template<typename _CharT, typename _Traits>
  902. class basic_fstream : public basic_iostream<_CharT, _Traits>
  903. {
  904. public:
  905. // Types:
  906. typedef _CharT char_type;
  907. typedef _Traits traits_type;
  908. typedef typename traits_type::int_type int_type;
  909. typedef typename traits_type::pos_type pos_type;
  910. typedef typename traits_type::off_type off_type;
  911. // Non-standard types:
  912. typedef basic_filebuf<char_type, traits_type> __filebuf_type;
  913. typedef basic_ios<char_type, traits_type> __ios_type;
  914. typedef basic_iostream<char_type, traits_type> __iostream_type;
  915. private:
  916. __filebuf_type _M_filebuf;
  917. public:
  918. // Constructors/destructor:
  919. /**
  920. * @brief Default constructor.
  921. *
  922. * Initializes @c sb using its default constructor, and passes
  923. * @c &sb to the base class initializer. Does not open any files
  924. * (you haven't given it a filename to open).
  925. */
  926. basic_fstream()
  927. : __iostream_type(), _M_filebuf()
  928. { this->init(&_M_filebuf); }
  929. /**
  930. * @brief Create an input/output file stream.
  931. * @param __s Null terminated string specifying the filename.
  932. * @param __mode Open file in specified mode (see std::ios_base).
  933. */
  934. explicit
  935. basic_fstream(const char* __s,
  936. ios_base::openmode __mode = ios_base::in | ios_base::out)
  937. : __iostream_type(0), _M_filebuf()
  938. {
  939. this->init(&_M_filebuf);
  940. this->open(__s, __mode);
  941. }
  942. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  943. /**
  944. * @param Create an input/output file stream.
  945. * @param __s Wide string specifying the filename.
  946. * @param __mode Open file in specified mode (see std::ios_base).
  947. */
  948. basic_fstream(const wchar_t* __s,
  949. ios_base::openmode __mode = ios_base::in | ios_base::out)
  950. : __iostream_type(0), _M_filebuf()
  951. {
  952. this->init(&_M_filebuf);
  953. this->open(__s, __mode);
  954. }
  955. #endif
  956. #if __cplusplus >= 201103L
  957. /**
  958. * @brief Create an input/output file stream.
  959. * @param __s Null terminated string specifying the filename.
  960. * @param __mode Open file in specified mode (see std::ios_base).
  961. */
  962. explicit
  963. basic_fstream(const std::string& __s,
  964. ios_base::openmode __mode = ios_base::in | ios_base::out)
  965. : __iostream_type(0), _M_filebuf()
  966. {
  967. this->init(&_M_filebuf);
  968. this->open(__s, __mode);
  969. }
  970. #if __cplusplus >= 201703L
  971. /**
  972. * @brief Create an input/output file stream.
  973. * @param __s filesystem::path specifying the filename.
  974. * @param __mode Open file in specified mode (see std::ios_base).
  975. */
  976. template<typename _Path, typename _Require = _If_fs_path<_Path>>
  977. basic_fstream(const _Path& __s,
  978. ios_base::openmode __mode = ios_base::in | ios_base::out)
  979. : basic_fstream(__s.c_str(), __mode)
  980. { }
  981. #endif // C++17
  982. basic_fstream(const basic_fstream&) = delete;
  983. basic_fstream(basic_fstream&& __rhs)
  984. : __iostream_type(std::move(__rhs)),
  985. _M_filebuf(std::move(__rhs._M_filebuf))
  986. { __iostream_type::set_rdbuf(&_M_filebuf); }
  987. #endif
  988. /**
  989. * @brief The destructor does nothing.
  990. *
  991. * The file is closed by the filebuf object, not the formatting
  992. * stream.
  993. */
  994. ~basic_fstream()
  995. { }
  996. #if __cplusplus >= 201103L
  997. // 27.8.3.2 Assign and swap:
  998. basic_fstream&
  999. operator=(const basic_fstream&) = delete;
  1000. basic_fstream&
  1001. operator=(basic_fstream&& __rhs)
  1002. {
  1003. __iostream_type::operator=(std::move(__rhs));
  1004. _M_filebuf = std::move(__rhs._M_filebuf);
  1005. return *this;
  1006. }
  1007. void
  1008. swap(basic_fstream& __rhs)
  1009. {
  1010. __iostream_type::swap(__rhs);
  1011. _M_filebuf.swap(__rhs._M_filebuf);
  1012. }
  1013. #endif
  1014. // Members:
  1015. /**
  1016. * @brief Accessing the underlying buffer.
  1017. * @return The current basic_filebuf buffer.
  1018. *
  1019. * This hides both signatures of std::basic_ios::rdbuf().
  1020. */
  1021. __filebuf_type*
  1022. rdbuf() const
  1023. { return const_cast<__filebuf_type*>(&_M_filebuf); }
  1024. /**
  1025. * @brief Wrapper to test for an open file.
  1026. * @return @c rdbuf()->is_open()
  1027. */
  1028. bool
  1029. is_open()
  1030. { return _M_filebuf.is_open(); }
  1031. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1032. // 365. Lack of const-qualification in clause 27
  1033. bool
  1034. is_open() const
  1035. { return _M_filebuf.is_open(); }
  1036. /**
  1037. * @brief Opens an external file.
  1038. * @param __s The name of the file.
  1039. * @param __mode The open mode flags.
  1040. *
  1041. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  1042. * function fails, @c failbit is set in the stream's error state.
  1043. */
  1044. void
  1045. open(const char* __s,
  1046. ios_base::openmode __mode = ios_base::in | ios_base::out)
  1047. {
  1048. if (!_M_filebuf.open(__s, __mode))
  1049. this->setstate(ios_base::failbit);
  1050. else
  1051. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1052. // 409. Closing an fstream should clear error state
  1053. this->clear();
  1054. }
  1055. #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
  1056. /**
  1057. * @brief Opens an external file.
  1058. * @param __s The name of the file.
  1059. * @param __mode The open mode flags.
  1060. *
  1061. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  1062. * function fails, @c failbit is set in the stream's error state.
  1063. */
  1064. void
  1065. open(const wchar_t* __s,
  1066. ios_base::openmode __mode = ios_base::in | ios_base::out)
  1067. {
  1068. if (!_M_filebuf.open(__s, __mode))
  1069. this->setstate(ios_base::failbit);
  1070. else
  1071. this->clear();
  1072. }
  1073. #endif
  1074. #if __cplusplus >= 201103L
  1075. /**
  1076. * @brief Opens an external file.
  1077. * @param __s The name of the file.
  1078. * @param __mode The open mode flags.
  1079. *
  1080. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  1081. * function fails, @c failbit is set in the stream's error state.
  1082. */
  1083. void
  1084. open(const std::string& __s,
  1085. ios_base::openmode __mode = ios_base::in | ios_base::out)
  1086. {
  1087. if (!_M_filebuf.open(__s, __mode))
  1088. this->setstate(ios_base::failbit);
  1089. else
  1090. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1091. // 409. Closing an fstream should clear error state
  1092. this->clear();
  1093. }
  1094. #if __cplusplus >= 201703L
  1095. /**
  1096. * @brief Opens an external file.
  1097. * @param __s The name of the file, as a filesystem::path.
  1098. * @param __mode The open mode flags.
  1099. *
  1100. * Calls @c std::basic_filebuf::open(__s,__mode). If that
  1101. * function fails, @c failbit is set in the stream's error state.
  1102. */
  1103. template<typename _Path>
  1104. _If_fs_path<_Path, void>
  1105. open(const _Path& __s,
  1106. ios_base::openmode __mode = ios_base::in | ios_base::out)
  1107. { open(__s.c_str(), __mode); }
  1108. #endif // C++17
  1109. #endif // C++11
  1110. /**
  1111. * @brief Close the file.
  1112. *
  1113. * Calls @c std::basic_filebuf::close(). If that function
  1114. * fails, @c failbit is set in the stream's error state.
  1115. */
  1116. void
  1117. close()
  1118. {
  1119. if (!_M_filebuf.close())
  1120. this->setstate(ios_base::failbit);
  1121. }
  1122. };
  1123. #if __cplusplus >= 201103L
  1124. /// Swap specialization for filebufs.
  1125. template <class _CharT, class _Traits>
  1126. inline void
  1127. swap(basic_filebuf<_CharT, _Traits>& __x,
  1128. basic_filebuf<_CharT, _Traits>& __y)
  1129. { __x.swap(__y); }
  1130. /// Swap specialization for ifstreams.
  1131. template <class _CharT, class _Traits>
  1132. inline void
  1133. swap(basic_ifstream<_CharT, _Traits>& __x,
  1134. basic_ifstream<_CharT, _Traits>& __y)
  1135. { __x.swap(__y); }
  1136. /// Swap specialization for ofstreams.
  1137. template <class _CharT, class _Traits>
  1138. inline void
  1139. swap(basic_ofstream<_CharT, _Traits>& __x,
  1140. basic_ofstream<_CharT, _Traits>& __y)
  1141. { __x.swap(__y); }
  1142. /// Swap specialization for fstreams.
  1143. template <class _CharT, class _Traits>
  1144. inline void
  1145. swap(basic_fstream<_CharT, _Traits>& __x,
  1146. basic_fstream<_CharT, _Traits>& __y)
  1147. { __x.swap(__y); }
  1148. #endif
  1149. _GLIBCXX_END_NAMESPACE_VERSION
  1150. } // namespace
  1151. #include <bits/fstream.tcc>
  1152. #endif /* _GLIBCXX_FSTREAM */