fstream.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // boost/filesystem/fstream.hpp ------------------------------------------------------//
  2. // Copyright Beman Dawes 2002
  3. // Copyright Andrey Semashev 2021-2023
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See http://www.boost.org/LICENSE_1_0.txt
  6. // Library home page: http://www.boost.org/libs/filesystem
  7. //--------------------------------------------------------------------------------------//
  8. #ifndef BOOST_FILESYSTEM_FSTREAM_HPP
  9. #define BOOST_FILESYSTEM_FSTREAM_HPP
  10. #include <boost/filesystem/config.hpp>
  11. #include <boost/filesystem/path.hpp>
  12. #include <cstddef>
  13. #include <iosfwd>
  14. #include <fstream>
  15. #include <boost/filesystem/detail/header.hpp> // must be the last #include
  16. #if defined(BOOST_WINDOWS_API)
  17. // On Windows, except for standard libaries known to have wchar_t overloads for
  18. // file stream I/O, use path::string() to get a narrow character c_str()
  19. #if (defined(_CPPLIB_VER) && _CPPLIB_VER >= 405 && !defined(_STLPORT_VERSION)) || \
  20. (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 7000 && defined(_LIBCPP_HAS_OPEN_WITH_WCHAR))
  21. // Use wide characters directly
  22. // Note: We don't use C++17 std::filesystem::path as a means to pass wide paths
  23. // to file streams because of various problems:
  24. // - std::filesystem is available in gcc 8 but it is broken there (fails to compile path definition
  25. // on Windows). Compilation errors seem to be fixed since gcc 9.
  26. // - In gcc 10.2 and clang 8.0.1 on Cygwin64, the path attempts to convert the wide string to narrow
  27. // and fails in runtime. This may be system locale dependent, and performing character code conversion
  28. // is against the purpose of using std::filesystem::path anyway.
  29. // - Other std::filesystem implementations were not tested, so it is not known if they actually work
  30. // with wide paths.
  31. #define BOOST_FILESYSTEM_C_STR(p) p.c_str()
  32. #else
  33. // Use narrow characters, since wide not available
  34. #define BOOST_FILESYSTEM_C_STR(p) p.string().c_str()
  35. #endif
  36. #endif // defined(BOOST_WINDOWS_API)
  37. #if !defined(BOOST_FILESYSTEM_C_STR)
  38. #define BOOST_FILESYSTEM_C_STR(p) p.c_str()
  39. #endif
  40. #if defined(BOOST_MSVC)
  41. #pragma warning(push)
  42. // 'boost::filesystem::basic_fstream<Char>' : inherits 'std::basic_istream<_Elem,_Traits>::std::basic_istream<_Elem,_Traits>::_Add_vtordisp1' via dominance
  43. #pragma warning(disable : 4250)
  44. #endif
  45. namespace boost {
  46. namespace filesystem {
  47. //--------------------------------------------------------------------------------------//
  48. // basic_filebuf //
  49. //--------------------------------------------------------------------------------------//
  50. template< class Char, class Traits = std::char_traits< Char > >
  51. class basic_filebuf :
  52. public std::basic_filebuf< Char, Traits >
  53. {
  54. private:
  55. typedef std::basic_filebuf< Char, Traits > base_type;
  56. public:
  57. BOOST_DEFAULTED_FUNCTION(basic_filebuf(), {})
  58. #if !defined(BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS)
  59. #if !defined(BOOST_NO_CXX11_DEFAULTED_MOVES)
  60. basic_filebuf(basic_filebuf&&) = default;
  61. basic_filebuf& operator= (basic_filebuf&&) = default;
  62. #else
  63. basic_filebuf(basic_filebuf&& that) :
  64. base_type(static_cast< base_type&& >(that)) {}
  65. basic_filebuf& operator= (basic_filebuf&& that)
  66. {
  67. *static_cast< base_type* >(this) = static_cast< base_type&& >(that);
  68. return *this;
  69. }
  70. #endif
  71. #endif // !defined(BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS)
  72. BOOST_DELETED_FUNCTION(basic_filebuf(basic_filebuf const&))
  73. BOOST_DELETED_FUNCTION(basic_filebuf const& operator= (basic_filebuf const&))
  74. public:
  75. basic_filebuf* open(path const& p, std::ios_base::openmode mode)
  76. {
  77. return base_type::open(BOOST_FILESYSTEM_C_STR(p), mode) ? this : NULL;
  78. }
  79. };
  80. //--------------------------------------------------------------------------------------//
  81. // basic_ifstream //
  82. //--------------------------------------------------------------------------------------//
  83. template< class Char, class Traits = std::char_traits< Char > >
  84. class basic_ifstream :
  85. public std::basic_ifstream< Char, Traits >
  86. {
  87. private:
  88. typedef std::basic_ifstream< Char, Traits > base_type;
  89. public:
  90. BOOST_DEFAULTED_FUNCTION(basic_ifstream(), {})
  91. // use two signatures, rather than one signature with default second
  92. // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
  93. explicit basic_ifstream(path const& p) :
  94. base_type(BOOST_FILESYSTEM_C_STR(p), std::ios_base::in) {}
  95. basic_ifstream(path const& p, std::ios_base::openmode mode) :
  96. base_type(BOOST_FILESYSTEM_C_STR(p), mode) {}
  97. #if !defined(BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS)
  98. basic_ifstream(basic_ifstream&& that) :
  99. base_type(static_cast< base_type&& >(that)) {}
  100. basic_ifstream& operator= (basic_ifstream&& that)
  101. {
  102. *static_cast< base_type* >(this) = static_cast< base_type&& >(that);
  103. return *this;
  104. }
  105. #endif
  106. BOOST_DELETED_FUNCTION(basic_ifstream(basic_ifstream const&))
  107. BOOST_DELETED_FUNCTION(basic_ifstream const& operator= (basic_ifstream const&))
  108. public:
  109. void open(path const& p)
  110. {
  111. base_type::open(BOOST_FILESYSTEM_C_STR(p), std::ios_base::in);
  112. }
  113. void open(path const& p, std::ios_base::openmode mode)
  114. {
  115. base_type::open(BOOST_FILESYSTEM_C_STR(p), mode);
  116. }
  117. };
  118. //--------------------------------------------------------------------------------------//
  119. // basic_ofstream //
  120. //--------------------------------------------------------------------------------------//
  121. template< class Char, class Traits = std::char_traits< Char > >
  122. class basic_ofstream :
  123. public std::basic_ofstream< Char, Traits >
  124. {
  125. private:
  126. typedef std::basic_ofstream< Char, Traits > base_type;
  127. public:
  128. BOOST_DEFAULTED_FUNCTION(basic_ofstream(), {})
  129. // use two signatures, rather than one signature with default second
  130. // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
  131. explicit basic_ofstream(path const& p) :
  132. base_type(BOOST_FILESYSTEM_C_STR(p), std::ios_base::out) {}
  133. basic_ofstream(path const& p, std::ios_base::openmode mode) :
  134. base_type(BOOST_FILESYSTEM_C_STR(p), mode) {}
  135. #if !defined(BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS)
  136. basic_ofstream(basic_ofstream&& that) :
  137. base_type(static_cast< base_type&& >(that)) {}
  138. basic_ofstream& operator= (basic_ofstream&& that)
  139. {
  140. *static_cast< base_type* >(this) = static_cast< base_type&& >(that);
  141. return *this;
  142. }
  143. #endif
  144. BOOST_DELETED_FUNCTION(basic_ofstream(basic_ofstream const&))
  145. BOOST_DELETED_FUNCTION(basic_ofstream const& operator= (basic_ofstream const&))
  146. public:
  147. void open(path const& p)
  148. {
  149. base_type::open(BOOST_FILESYSTEM_C_STR(p), std::ios_base::out);
  150. }
  151. void open(path const& p, std::ios_base::openmode mode)
  152. {
  153. base_type::open(BOOST_FILESYSTEM_C_STR(p), mode);
  154. }
  155. };
  156. //--------------------------------------------------------------------------------------//
  157. // basic_fstream //
  158. //--------------------------------------------------------------------------------------//
  159. template< class Char, class Traits = std::char_traits< Char > >
  160. class basic_fstream :
  161. public std::basic_fstream< Char, Traits >
  162. {
  163. private:
  164. typedef std::basic_fstream< Char, Traits > base_type;
  165. public:
  166. BOOST_DEFAULTED_FUNCTION(basic_fstream(), {})
  167. // use two signatures, rather than one signature with default second
  168. // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
  169. explicit basic_fstream(path const& p) :
  170. base_type(BOOST_FILESYSTEM_C_STR(p), std::ios_base::in | std::ios_base::out) {}
  171. basic_fstream(path const& p, std::ios_base::openmode mode) :
  172. base_type(BOOST_FILESYSTEM_C_STR(p), mode) {}
  173. #if !defined(BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS)
  174. basic_fstream(basic_fstream&& that) :
  175. base_type(static_cast< base_type&& >(that)) {}
  176. basic_fstream& operator= (basic_fstream&& that)
  177. {
  178. *static_cast< base_type* >(this) = static_cast< base_type&& >(that);
  179. return *this;
  180. }
  181. #endif
  182. BOOST_DELETED_FUNCTION(basic_fstream(basic_fstream const&))
  183. BOOST_DELETED_FUNCTION(basic_fstream const& operator= (basic_fstream const&))
  184. public:
  185. void open(path const& p)
  186. {
  187. base_type::open(BOOST_FILESYSTEM_C_STR(p), std::ios_base::in | std::ios_base::out);
  188. }
  189. void open(path const& p, std::ios_base::openmode mode)
  190. {
  191. base_type::open(BOOST_FILESYSTEM_C_STR(p), mode);
  192. }
  193. };
  194. //--------------------------------------------------------------------------------------//
  195. // typedefs //
  196. //--------------------------------------------------------------------------------------//
  197. typedef basic_filebuf< char > filebuf;
  198. typedef basic_ifstream< char > ifstream;
  199. typedef basic_ofstream< char > ofstream;
  200. typedef basic_fstream< char > fstream;
  201. typedef basic_filebuf< wchar_t > wfilebuf;
  202. typedef basic_ifstream< wchar_t > wifstream;
  203. typedef basic_ofstream< wchar_t > wofstream;
  204. typedef basic_fstream< wchar_t > wfstream;
  205. } // namespace filesystem
  206. } // namespace boost
  207. #if defined(BOOST_MSVC)
  208. #pragma warning(pop)
  209. #endif
  210. #include <boost/filesystem/detail/footer.hpp>
  211. #endif // BOOST_FILESYSTEM_FSTREAM_HPP