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

source code of boost/libs/filesystem/include/boost/filesystem/fstream.hpp