Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
Boost.Nowide
fstream.hpp
1 //
2 // Copyright (c) 2012 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // https://www.boost.org/LICENSE_1_0.txt
6 
7 #ifndef BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
8 #define BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
9 
10 #include <boost/nowide/config.hpp>
11 #include <boost/nowide/detail/is_path.hpp>
12 #include <boost/nowide/filebuf.hpp>
13 #include <istream>
14 #include <ostream>
15 #include <utility>
16 
17 namespace boost {
18 namespace nowide {
20  namespace detail {
21  // clang-format off
22  struct StreamTypeIn
23  {
24  static std::ios_base::openmode mode() { return std::ios_base::in; }
25  static std::ios_base::openmode mode_modifier() { return mode(); }
26  template<typename CharType, typename Traits>
27  struct stream_base{
28  using type = std::basic_istream<CharType, Traits>;
29  };
30  };
31  struct StreamTypeOut
32  {
33  static std::ios_base::openmode mode() { return std::ios_base::out; }
34  static std::ios_base::openmode mode_modifier() { return mode(); }
35  template<typename CharType, typename Traits>
36  struct stream_base{
37  using type = std::basic_ostream<CharType, Traits>;
38  };
39  };
40  struct StreamTypeInOut
41  {
42  static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
43  static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
44  template<typename CharType, typename Traits>
45  struct stream_base{
46  using type = std::basic_iostream<CharType, Traits>;
47  };
48  };
49  // clang-format on
50 
58  template<typename CharType,
59  typename Traits,
60  typename T_StreamType,
61  int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
62  class fstream_impl;
63 
64  } // namespace detail
66 
71  template<typename CharType, typename Traits = std::char_traits<CharType>>
72  class basic_ifstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>
73  {
74  using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>;
75 
76  public:
78  {}
79 
80  explicit basic_ifstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::in)
81  {
82  open(file_name, mode);
83  }
84 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
85  explicit basic_ifstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::in)
86  {
87  open(file_name, mode);
88  }
89 #endif
90 
91  explicit basic_ifstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in)
92  {
93  open(file_name, mode);
94  }
95 
96  template<typename Path>
97  explicit basic_ifstream(const Path& file_name,
98  detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in)
99  {
100  open(file_name, mode);
101  }
102  using fstream_impl::open;
103  using fstream_impl::is_open;
104  using fstream_impl::close;
105  using fstream_impl::rdbuf;
106  using fstream_impl::swap;
107  basic_ifstream(const basic_ifstream&) = delete;
108  basic_ifstream& operator=(const basic_ifstream&) = delete;
109  basic_ifstream(basic_ifstream&& other) noexcept : fstream_impl(std::move(other))
110  {}
111  basic_ifstream& operator=(basic_ifstream&& rhs) noexcept
112  {
113  fstream_impl::operator=(std::move(rhs));
114  return *this;
115  }
116  };
117 
122  template<typename CharType, typename Traits = std::char_traits<CharType>>
123  class basic_ofstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>
124  {
125  using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>;
126 
127  public:
129  {}
130  explicit basic_ofstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::out)
131  {
132  open(file_name, mode);
133  }
134 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
135  explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
136  {
137  open(file_name, mode);
138  }
139 #endif
140  explicit basic_ofstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::out)
141  {
142  open(file_name, mode);
143  }
144  template<typename Path>
145  explicit basic_ofstream(const Path& file_name,
146  detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::out)
147  {
148  open(file_name, mode);
149  }
150 
151  using fstream_impl::open;
152  using fstream_impl::is_open;
153  using fstream_impl::close;
154  using fstream_impl::rdbuf;
155  using fstream_impl::swap;
156  basic_ofstream(const basic_ofstream&) = delete;
157  basic_ofstream& operator=(const basic_ofstream&) = delete;
158  basic_ofstream(basic_ofstream&& other) noexcept : fstream_impl(std::move(other))
159  {}
160  basic_ofstream& operator=(basic_ofstream&& rhs)
161  {
162  fstream_impl::operator=(std::move(rhs));
163  return *this;
164  }
165  };
166 
167 #ifdef BOOST_MSVC
168 #pragma warning(push)
169 #pragma warning(disable : 4250) // <class> : inherits <method> via dominance
170 #endif
171  template<typename CharType, typename Traits = std::char_traits<CharType>>
176  class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
177  {
178  using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>;
179 
180  public:
181  basic_fstream()
182  {}
183  explicit basic_fstream(const char* file_name,
184  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
185  {
186  open(file_name, mode);
187  }
188 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
189  explicit basic_fstream(const wchar_t* file_name,
190  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
191  {
192  open(file_name, mode);
193  }
194 #endif
195  explicit basic_fstream(const std::string& file_name,
196  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
197  {
198  open(file_name, mode);
199  }
200  template<typename Path>
201  explicit basic_fstream(const Path& file_name,
202  detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in
203  | std::ios_base::out)
204  {
205  open(file_name, mode);
206  }
207 
208  using fstream_impl::open;
209  using fstream_impl::is_open;
210  using fstream_impl::close;
211  using fstream_impl::rdbuf;
212  using fstream_impl::swap;
213  basic_fstream(const basic_fstream&) = delete;
214  basic_fstream& operator=(const basic_fstream&) = delete;
215  basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
216  {}
217  basic_fstream& operator=(basic_fstream&& rhs)
218  {
219  fstream_impl::operator=(std::move(rhs));
220  return *this;
221  }
222  };
223 
224  template<typename CharType, typename Traits>
226  {
227  lhs.swap(rhs);
228  }
229  template<typename CharType, typename Traits>
230  void swap(basic_ofstream<CharType, Traits>& lhs, basic_ofstream<CharType, Traits>& rhs)
231  {
232  lhs.swap(rhs);
233  }
234  template<typename CharType, typename Traits>
235  void swap(basic_fstream<CharType, Traits>& lhs, basic_fstream<CharType, Traits>& rhs)
236  {
237  lhs.swap(rhs);
238  }
239 
243  using filebuf = basic_filebuf<char>;
259 
260  // Implementation
261  namespace detail {
264  template<typename T>
265  struct buf_holder
266  {
267  T buf_;
268  };
269  template<typename CharType, typename Traits, typename T_StreamType, int>
270  class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits>>, // must be first due to init order
271  public T_StreamType::template stream_base<CharType, Traits>::type
272  {
273  using internal_buffer_type = basic_filebuf<CharType, Traits>;
274  using base_buf_holder = buf_holder<internal_buffer_type>;
275  using stream_base = typename T_StreamType::template stream_base<CharType, Traits>::type;
276 
277  public:
278  using stream_base::setstate;
279  using stream_base::clear;
280 
281  protected:
282  using base_buf_holder::buf_;
283 
284  fstream_impl() : stream_base(&buf_)
285  {}
286  fstream_impl(const fstream_impl&) = delete;
287  fstream_impl& operator=(const fstream_impl&) = delete;
288 
289  // coverity[exn_spec_violation]
290  fstream_impl(fstream_impl&& other) noexcept :
291  base_buf_holder(std::move(other)), stream_base(std::move(other))
292  {
293  this->set_rdbuf(rdbuf());
294  }
295  fstream_impl& operator=(fstream_impl&& rhs) noexcept
296  {
297  base_buf_holder::operator=(std::move(rhs));
298  stream_base::operator=(std::move(rhs));
299  return *this;
300  }
301  void swap(fstream_impl& other)
302  {
303  stream_base::swap(other);
304  rdbuf()->swap(*other.rdbuf());
305  }
306 
307  void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
308  {
309  open(file_name.c_str(), mode);
310  }
311  template<typename Path>
312  detail::enable_if_path_t<Path, void> open(const Path& file_name,
313  std::ios_base::openmode mode = T_StreamType::mode())
314  {
315  open(file_name.c_str(), mode);
316  }
317  void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
318  {
319  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
320  setstate(std::ios_base::failbit);
321  else
322  clear();
323  }
324 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
325  void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
326  {
327  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
328  setstate(std::ios_base::failbit);
329  else
330  clear();
331  }
332 #endif
333  bool is_open()
334  {
335  return rdbuf()->is_open();
336  }
337  bool is_open() const
338  {
339  return rdbuf()->is_open();
340  }
341  void close()
342  {
343  if(!rdbuf()->close())
344  setstate(std::ios_base::failbit);
345  }
346 
347  internal_buffer_type* rdbuf() const
348  {
349  return const_cast<internal_buffer_type*>(&buf_);
350  }
351  };
352 #ifdef BOOST_MSVC
353 #pragma warning(pop)
354 #endif
355  } // namespace detail
356 } // namespace nowide
357 } // namespace boost
358 
359 #endif
basic_filebuf< char > filebuf
Convenience typedef.
Definition: filebuf.hpp:532
Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:72
This forward declaration defines the basic_filebuf type which is used when BOOST_NOWIDE_USE_FILEBUF_R...
Definition: filebuf.hpp:48
Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:176
Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:123
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
Define to 1 to use the class from <filebuf.hpp> that is used on Windows.
Definition: config.hpp:76
void swap(basic_filebuf< CharType, Traits > &lhs, basic_filebuf< CharType, Traits > &rhs)
Swap the basic_filebuf instances.
Definition: filebuf.hpp:536