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. (See
5 // accompanying file LICENSE or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
9 #define BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
10 
11 #include <boost/nowide/config.hpp>
12 #include <boost/nowide/detail/is_path.hpp>
13 #include <boost/nowide/filebuf.hpp>
14 #include <istream>
15 #include <ostream>
16 #include <utility>
17 
18 namespace boost {
19 namespace nowide {
21  namespace detail {
22  // clang-format off
23  struct StreamTypeIn
24  {
25  static std::ios_base::openmode mode() { return std::ios_base::in; }
26  static std::ios_base::openmode mode_modifier() { return mode(); }
27  template<typename CharType, typename Traits>
28  struct stream_base{
29  using type = std::basic_istream<CharType, Traits>;
30  };
31  };
32  struct StreamTypeOut
33  {
34  static std::ios_base::openmode mode() { return std::ios_base::out; }
35  static std::ios_base::openmode mode_modifier() { return mode(); }
36  template<typename CharType, typename Traits>
37  struct stream_base{
38  using type = std::basic_ostream<CharType, Traits>;
39  };
40  };
41  struct StreamTypeInOut
42  {
43  static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
44  static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
45  template<typename CharType, typename Traits>
46  struct stream_base{
47  using type = std::basic_iostream<CharType, Traits>;
48  };
49  };
50  // clang-format on
51 
59  template<typename CharType,
60  typename Traits,
61  typename T_StreamType,
62  int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
63  class fstream_impl;
64 
65  } // namespace detail
67 
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 
121 
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>>
175  class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
176  {
177  using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>;
178 
179  public:
180  basic_fstream()
181  {}
182  explicit basic_fstream(const char* file_name,
183  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
184  {
185  open(file_name, mode);
186  }
187 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
188  explicit basic_fstream(const wchar_t* file_name,
189  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
190  {
191  open(file_name, mode);
192  }
193 #endif
194  explicit basic_fstream(const std::string& file_name,
195  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
196  {
197  open(file_name, mode);
198  }
199  template<typename Path>
200  explicit basic_fstream(const Path& file_name,
201  detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in
202  | std::ios_base::out)
203  {
204  open(file_name, mode);
205  }
206 
207  using fstream_impl::open;
208  using fstream_impl::is_open;
209  using fstream_impl::close;
210  using fstream_impl::rdbuf;
211  using fstream_impl::swap;
212  basic_fstream(const basic_fstream&) = delete;
213  basic_fstream& operator=(const basic_fstream&) = delete;
214  basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
215  {}
216  basic_fstream& operator=(basic_fstream&& rhs)
217  {
218  fstream_impl::operator=(std::move(rhs));
219  return *this;
220  }
221  };
222 
223  template<typename CharType, typename Traits>
225  {
226  lhs.swap(rhs);
227  }
228  template<typename CharType, typename Traits>
229  void swap(basic_ofstream<CharType, Traits>& lhs, basic_ofstream<CharType, Traits>& rhs)
230  {
231  lhs.swap(rhs);
232  }
233  template<typename CharType, typename Traits>
234  void swap(basic_fstream<CharType, Traits>& lhs, basic_fstream<CharType, Traits>& rhs)
235  {
236  lhs.swap(rhs);
237  }
238 
242  using filebuf = basic_filebuf<char>;
258 
259  // Implementation
260  namespace detail {
263  template<typename T>
264  struct buf_holder
265  {
266  T buf_;
267  };
268  template<typename CharType, typename Traits, typename T_StreamType, int>
269  class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits>>, // must be first due to init order
270  public T_StreamType::template stream_base<CharType, Traits>::type
271  {
272  using internal_buffer_type = basic_filebuf<CharType, Traits>;
273  using base_buf_holder = buf_holder<internal_buffer_type>;
274  using stream_base = typename T_StreamType::template stream_base<CharType, Traits>::type;
275 
276  public:
277  using stream_base::setstate;
278  using stream_base::clear;
279 
280  protected:
281  using base_buf_holder::buf_;
282 
283  fstream_impl() : stream_base(&buf_)
284  {}
285  fstream_impl(const fstream_impl&) = delete;
286  fstream_impl& operator=(const fstream_impl&) = delete;
287 
288  // coverity[exn_spec_violation]
289  fstream_impl(fstream_impl&& other) noexcept :
290  base_buf_holder(std::move(other)), stream_base(std::move(other))
291  {
292  this->set_rdbuf(rdbuf());
293  }
294  fstream_impl& operator=(fstream_impl&& rhs) noexcept
295  {
296  base_buf_holder::operator=(std::move(rhs));
297  stream_base::operator=(std::move(rhs));
298  return *this;
299  }
300  void swap(fstream_impl& other)
301  {
302  stream_base::swap(other);
303  rdbuf()->swap(*other.rdbuf());
304  }
305 
306  void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
307  {
308  open(file_name.c_str(), mode);
309  }
310  template<typename Path>
311  detail::enable_if_path_t<Path, void> open(const Path& file_name,
312  std::ios_base::openmode mode = T_StreamType::mode())
313  {
314  open(file_name.c_str(), mode);
315  }
316  void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
317  {
318  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
319  setstate(std::ios_base::failbit);
320  else
321  clear();
322  }
323 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
324  void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
325  {
326  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
327  setstate(std::ios_base::failbit);
328  else
329  clear();
330  }
331 #endif
332  bool is_open()
333  {
334  return rdbuf()->is_open();
335  }
336  bool is_open() const
337  {
338  return rdbuf()->is_open();
339  }
340  void close()
341  {
342  if(!rdbuf()->close())
343  setstate(std::ios_base::failbit);
344  }
345 
346  internal_buffer_type* rdbuf() const
347  {
348  return const_cast<internal_buffer_type*>(&buf_);
349  }
350  };
351 #ifdef BOOST_MSVC
352 #pragma warning(pop)
353 #endif
354  } // namespace detail
355 } // namespace nowide
356 } // namespace boost
357 
358 #endif
basic_filebuf< char > filebuf
Convenience typedef.
Definition: filebuf.hpp:476
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.
Definition: filebuf.hpp:47
Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:175
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 internal class from filebuf.hpp.
Definition: config.hpp:77
void swap(basic_filebuf< CharType, Traits > &lhs, basic_filebuf< CharType, Traits > &rhs)
Swap the basic_filebuf instances.
Definition: filebuf.hpp:480