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/filebuf.hpp>
13 #include <istream>
14 #include <ostream>
15 
16 namespace boost {
17 namespace nowide {
19  namespace detail {
20  // clang-format off
21  struct StreamTypeIn
22  {
23  static std::ios_base::openmode mode() { return std::ios_base::in; }
24  static std::ios_base::openmode mode_modifier() { return mode(); }
25  template<typename CharType, typename Traits>
26  struct stream_base{
27  typedef std::basic_istream<CharType, Traits> type;
28  };
29  };
30  struct StreamTypeOut
31  {
32  static std::ios_base::openmode mode() { return std::ios_base::out; }
33  static std::ios_base::openmode mode_modifier() { return mode(); }
34  template<typename CharType, typename Traits>
35  struct stream_base{
36  typedef std::basic_ostream<CharType, Traits> type;
37  };
38  };
39  struct StreamTypeInOut
40  {
41  static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
42  static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
43  template<typename CharType, typename Traits>
44  struct stream_base{
45  typedef std::basic_iostream<CharType, Traits> type;
46  };
47  };
48  // clang-format on
49 
57  template<typename CharType,
58  typename Traits,
59  typename T_StreamType,
60  int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
61  class fstream_impl;
62 
63  template<typename Path, typename Result>
64  struct enable_if_path;
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  typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeIn> fstream_impl;
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(
98  const Path& file_name,
99  typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode = std::ios_base::in)
100  {
101  open(file_name, mode);
102  }
103  using fstream_impl::open;
104  using fstream_impl::is_open;
105  using fstream_impl::close;
106  using fstream_impl::rdbuf;
107  using fstream_impl::swap;
108  basic_ifstream(const basic_ifstream&) = delete;
109  basic_ifstream& operator=(const basic_ifstream&) = delete;
110  basic_ifstream(basic_ifstream&& other) noexcept : fstream_impl(std::move(other))
111  {}
112  basic_ifstream& operator=(basic_ifstream&& rhs) noexcept
113  {
114  fstream_impl::operator=(std::move(rhs));
115  return *this;
116  }
117  };
118 
122 
123  template<typename CharType, typename Traits = std::char_traits<CharType> >
124  class basic_ofstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>
125  {
126  typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeOut> fstream_impl;
127 
128  public:
130  {}
131  explicit basic_ofstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::out)
132  {
133  open(file_name, mode);
134  }
135 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
136  explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
137  {
138  open(file_name, mode);
139  }
140 #endif
141  explicit basic_ofstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::out)
142  {
143  open(file_name, mode);
144  }
145  template<typename Path>
146  explicit basic_ofstream(
147  const Path& file_name,
148  typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode = std::ios_base::out)
149  {
150  open(file_name, mode);
151  }
152 
153  using fstream_impl::open;
154  using fstream_impl::is_open;
155  using fstream_impl::close;
156  using fstream_impl::rdbuf;
157  using fstream_impl::swap;
158  basic_ofstream(const basic_ofstream&) = delete;
159  basic_ofstream& operator=(const basic_ofstream&) = delete;
160  basic_ofstream(basic_ofstream&& other) noexcept : fstream_impl(std::move(other))
161  {}
162  basic_ofstream& operator=(basic_ofstream&& rhs)
163  {
164  fstream_impl::operator=(std::move(rhs));
165  return *this;
166  }
167  };
168 
169 #ifdef BOOST_MSVC
170 #pragma warning(push)
171 #pragma warning(disable : 4250) // <class> : inherits <method> via dominance
172 #endif
173  template<typename CharType, typename Traits = std::char_traits<CharType> >
177  class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
178  {
179  typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut> fstream_impl;
180 
181  public:
182  basic_fstream()
183  {}
184  explicit basic_fstream(const char* file_name,
185  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
186  {
187  open(file_name, mode);
188  }
189 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
190  explicit basic_fstream(const wchar_t* file_name,
191  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
192  {
193  open(file_name, mode);
194  }
195 #endif
196  explicit basic_fstream(const std::string& file_name,
197  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
198  {
199  open(file_name, mode);
200  }
201  template<typename Path>
202  explicit basic_fstream(const Path& file_name,
203  typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode =
204  std::ios_base::in | std::ios_base::out)
205  {
206  open(file_name, mode);
207  }
208 
209  using fstream_impl::open;
210  using fstream_impl::is_open;
211  using fstream_impl::close;
212  using fstream_impl::rdbuf;
213  using fstream_impl::swap;
214  basic_fstream(const basic_fstream&) = delete;
215  basic_fstream& operator=(const basic_fstream&) = delete;
216  basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
217  {}
218  basic_fstream& operator=(basic_fstream&& rhs)
219  {
220  fstream_impl::operator=(std::move(rhs));
221  return *this;
222  }
223  };
224  template<typename CharType, typename Traits>
226  {
227  lhs.swap(rhs);
228  }
229  template<typename CharType, typename Traits>
230  void swap(basic_ifstream<CharType, Traits>& lhs, basic_ifstream<CharType, Traits>& rhs)
231  {
232  lhs.swap(rhs);
233  }
234  template<typename CharType, typename Traits>
235  void swap(basic_ofstream<CharType, Traits>& lhs, basic_ofstream<CharType, Traits>& rhs)
236  {
237  lhs.swap(rhs);
238  }
239  template<typename CharType, typename Traits>
240  void swap(basic_fstream<CharType, Traits>& lhs, basic_fstream<CharType, Traits>& rhs)
241  {
242  lhs.swap(rhs);
243  }
244 
248  typedef basic_filebuf<char> filebuf;
264 
265  // Implementation
266  namespace detail {
269  template<typename T>
270  struct buf_holder
271  {
272  T buf_;
273  };
274  template<typename CharType, typename Traits, typename T_StreamType, int>
275  class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits> >, // must be first due to init order
276  public T_StreamType::template stream_base<CharType, Traits>::type
277  {
278  typedef basic_filebuf<CharType, Traits> internal_buffer_type;
279  typedef buf_holder<internal_buffer_type> base_buf_holder;
280  typedef typename T_StreamType::template stream_base<CharType, Traits>::type stream_base;
281 
282  public:
283  using stream_base::setstate;
284  using stream_base::clear;
285 
286  protected:
287  using base_buf_holder::buf_;
288 
289  fstream_impl() : stream_base(&buf_)
290  {}
291  fstream_impl(const fstream_impl&) = delete;
292  fstream_impl& operator=(const fstream_impl&) = delete;
293 
294  // coverity[exn_spec_violation]
295  fstream_impl(fstream_impl&& other) noexcept : base_buf_holder(std::move(other)),
296  stream_base(std::move(other))
297  {
298  this->set_rdbuf(rdbuf());
299  }
300  fstream_impl& operator=(fstream_impl&& rhs) noexcept
301  {
302  base_buf_holder::operator=(std::move(rhs));
303  stream_base::operator=(std::move(rhs));
304  return *this;
305  }
306  void swap(fstream_impl& other)
307  {
308  stream_base::swap(other);
309  rdbuf()->swap(*other.rdbuf());
310  }
311 
312  void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
313  {
314  open(file_name.c_str(), mode);
315  }
316  template<typename Path>
317  typename detail::enable_if_path<Path, void>::type open(const Path& file_name,
318  std::ios_base::openmode mode = T_StreamType::mode())
319  {
320  open(file_name.c_str(), mode);
321  }
322  void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
323  {
324  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
325  setstate(std::ios_base::failbit);
326  else
327  clear();
328  }
329 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
330  void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
331  {
332  if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
333  setstate(std::ios_base::failbit);
334  else
335  clear();
336  }
337 #endif
338  bool is_open()
339  {
340  return rdbuf()->is_open();
341  }
342  bool is_open() const
343  {
344  return rdbuf()->is_open();
345  }
346  void close()
347  {
348  if(!rdbuf()->close())
349  setstate(std::ios_base::failbit);
350  }
351 
352  internal_buffer_type* rdbuf() const
353  {
354  return const_cast<internal_buffer_type*>(&buf_);
355  }
356  };
357 #ifdef BOOST_MSVC
358 #pragma warning(pop)
359 #endif
360  template<typename T>
363  struct is_path
364  {
365  typedef char one;
366  struct two
367  {
368  char dummy[2];
369  };
370 
371  template<typename U, U& (U::*)(), U (U::*)() const>
372  struct Check;
373  template<typename U>
374  static one test(Check<U, &U::make_preferred, &U::filename>*);
375  template<typename U>
376  static two test(...);
377 
378  enum
379  {
380  value = sizeof(test<T>(0)) == sizeof(one)
381  };
382  };
383  template<bool B, typename T>
384  struct enable_if
385  {};
386  template<typename T>
387  struct enable_if<true, T>
388  {
389  typedef T type;
390  };
392  template<typename Path, typename Result>
393  struct enable_if_path : enable_if<is_path<Path>::value, Result>
394  {};
395  } // namespace detail
396 } // namespace nowide
397 } // namespace boost
398 
399 #endif
basic_ifstream< char > ifstream
Definition: fstream.hpp:253
basic_filebuf< char > filebuf
Convenience typedef.
Definition: filebuf.hpp:464
Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:72
basic_ofstream< char > ofstream
Definition: fstream.hpp:258
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:177
Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows.
Definition: fstream.hpp:124
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
Define to 1 to use internal class from filebuf.hpp.
Definition: config.hpp:84
basic_fstream< char > fstream
Definition: fstream.hpp:263