File indexing completed on 2025-01-18 09:42:46
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
0008 #define BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
0009
0010 #include <boost/nowide/config.hpp>
0011 #include <boost/nowide/detail/is_path.hpp>
0012 #include <boost/nowide/filebuf.hpp>
0013 #include <istream>
0014 #include <ostream>
0015 #include <utility>
0016
0017 namespace boost {
0018 namespace nowide {
0019
0020 namespace detail {
0021
0022 struct StreamTypeIn
0023 {
0024 static std::ios_base::openmode mode() { return std::ios_base::in; }
0025 static std::ios_base::openmode mode_modifier() { return mode(); }
0026 template<typename CharType, typename Traits>
0027 struct stream_base{
0028 using type = std::basic_istream<CharType, Traits>;
0029 };
0030 };
0031 struct StreamTypeOut
0032 {
0033 static std::ios_base::openmode mode() { return std::ios_base::out; }
0034 static std::ios_base::openmode mode_modifier() { return mode(); }
0035 template<typename CharType, typename Traits>
0036 struct stream_base{
0037 using type = std::basic_ostream<CharType, Traits>;
0038 };
0039 };
0040 struct StreamTypeInOut
0041 {
0042 static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
0043 static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
0044 template<typename CharType, typename Traits>
0045 struct stream_base{
0046 using type = std::basic_iostream<CharType, Traits>;
0047 };
0048 };
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template<typename CharType,
0059 typename Traits,
0060 typename T_StreamType,
0061 int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
0062 class fstream_impl;
0063
0064 }
0065
0066
0067
0068
0069
0070
0071 template<typename CharType, typename Traits = std::char_traits<CharType>>
0072 class basic_ifstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>
0073 {
0074 using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>;
0075
0076 public:
0077 basic_ifstream()
0078 {}
0079
0080 explicit basic_ifstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::in)
0081 {
0082 open(file_name, mode);
0083 }
0084 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
0085 explicit basic_ifstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::in)
0086 {
0087 open(file_name, mode);
0088 }
0089 #endif
0090
0091 explicit basic_ifstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in)
0092 {
0093 open(file_name, mode);
0094 }
0095
0096 template<typename Path>
0097 explicit basic_ifstream(const Path& file_name,
0098 detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in)
0099 {
0100 open(file_name, mode);
0101 }
0102 using fstream_impl::open;
0103 using fstream_impl::is_open;
0104 using fstream_impl::close;
0105 using fstream_impl::rdbuf;
0106 using fstream_impl::swap;
0107 basic_ifstream(const basic_ifstream&) = delete;
0108 basic_ifstream& operator=(const basic_ifstream&) = delete;
0109 basic_ifstream(basic_ifstream&& other) noexcept : fstream_impl(std::move(other))
0110 {}
0111 basic_ifstream& operator=(basic_ifstream&& rhs) noexcept
0112 {
0113 fstream_impl::operator=(std::move(rhs));
0114 return *this;
0115 }
0116 };
0117
0118
0119
0120
0121
0122 template<typename CharType, typename Traits = std::char_traits<CharType>>
0123 class basic_ofstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>
0124 {
0125 using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>;
0126
0127 public:
0128 basic_ofstream()
0129 {}
0130 explicit basic_ofstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::out)
0131 {
0132 open(file_name, mode);
0133 }
0134 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
0135 explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
0136 {
0137 open(file_name, mode);
0138 }
0139 #endif
0140 explicit basic_ofstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::out)
0141 {
0142 open(file_name, mode);
0143 }
0144 template<typename Path>
0145 explicit basic_ofstream(const Path& file_name,
0146 detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::out)
0147 {
0148 open(file_name, mode);
0149 }
0150
0151 using fstream_impl::open;
0152 using fstream_impl::is_open;
0153 using fstream_impl::close;
0154 using fstream_impl::rdbuf;
0155 using fstream_impl::swap;
0156 basic_ofstream(const basic_ofstream&) = delete;
0157 basic_ofstream& operator=(const basic_ofstream&) = delete;
0158 basic_ofstream(basic_ofstream&& other) noexcept : fstream_impl(std::move(other))
0159 {}
0160 basic_ofstream& operator=(basic_ofstream&& rhs)
0161 {
0162 fstream_impl::operator=(std::move(rhs));
0163 return *this;
0164 }
0165 };
0166
0167 #ifdef BOOST_MSVC
0168 #pragma warning(push)
0169 #pragma warning(disable : 4250)
0170 #endif
0171
0172
0173
0174
0175 template<typename CharType, typename Traits = std::char_traits<CharType>>
0176 class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
0177 {
0178 using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>;
0179
0180 public:
0181 basic_fstream()
0182 {}
0183 explicit basic_fstream(const char* file_name,
0184 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
0185 {
0186 open(file_name, mode);
0187 }
0188 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
0189 explicit basic_fstream(const wchar_t* file_name,
0190 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
0191 {
0192 open(file_name, mode);
0193 }
0194 #endif
0195 explicit basic_fstream(const std::string& file_name,
0196 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
0197 {
0198 open(file_name, mode);
0199 }
0200 template<typename Path>
0201 explicit basic_fstream(const Path& file_name,
0202 detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in
0203 | std::ios_base::out)
0204 {
0205 open(file_name, mode);
0206 }
0207
0208 using fstream_impl::open;
0209 using fstream_impl::is_open;
0210 using fstream_impl::close;
0211 using fstream_impl::rdbuf;
0212 using fstream_impl::swap;
0213 basic_fstream(const basic_fstream&) = delete;
0214 basic_fstream& operator=(const basic_fstream&) = delete;
0215 basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
0216 {}
0217 basic_fstream& operator=(basic_fstream&& rhs)
0218 {
0219 fstream_impl::operator=(std::move(rhs));
0220 return *this;
0221 }
0222 };
0223
0224 template<typename CharType, typename Traits>
0225 void swap(basic_ifstream<CharType, Traits>& lhs, basic_ifstream<CharType, Traits>& rhs)
0226 {
0227 lhs.swap(rhs);
0228 }
0229 template<typename CharType, typename Traits>
0230 void swap(basic_ofstream<CharType, Traits>& lhs, basic_ofstream<CharType, Traits>& rhs)
0231 {
0232 lhs.swap(rhs);
0233 }
0234 template<typename CharType, typename Traits>
0235 void swap(basic_fstream<CharType, Traits>& lhs, basic_fstream<CharType, Traits>& rhs)
0236 {
0237 lhs.swap(rhs);
0238 }
0239
0240
0241
0242
0243 using filebuf = basic_filebuf<char>;
0244
0245
0246
0247
0248 using ifstream = basic_ifstream<char>;
0249
0250
0251
0252
0253 using ofstream = basic_ofstream<char>;
0254
0255
0256
0257
0258 using fstream = basic_fstream<char>;
0259
0260
0261 namespace detail {
0262
0263
0264 template<typename T>
0265 struct buf_holder
0266 {
0267 T buf_;
0268 };
0269 template<typename CharType, typename Traits, typename T_StreamType, int>
0270 class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits>>,
0271 public T_StreamType::template stream_base<CharType, Traits>::type
0272 {
0273 using internal_buffer_type = basic_filebuf<CharType, Traits>;
0274 using base_buf_holder = buf_holder<internal_buffer_type>;
0275 using stream_base = typename T_StreamType::template stream_base<CharType, Traits>::type;
0276
0277 public:
0278 using stream_base::setstate;
0279 using stream_base::clear;
0280
0281 protected:
0282 using base_buf_holder::buf_;
0283
0284 fstream_impl() : stream_base(&buf_)
0285 {}
0286 fstream_impl(const fstream_impl&) = delete;
0287 fstream_impl& operator=(const fstream_impl&) = delete;
0288
0289
0290 fstream_impl(fstream_impl&& other) noexcept :
0291 base_buf_holder(std::move(other)), stream_base(std::move(other))
0292 {
0293 this->set_rdbuf(rdbuf());
0294 }
0295 fstream_impl& operator=(fstream_impl&& rhs) noexcept
0296 {
0297 base_buf_holder::operator=(std::move(rhs));
0298 stream_base::operator=(std::move(rhs));
0299 return *this;
0300 }
0301 void swap(fstream_impl& other)
0302 {
0303 stream_base::swap(other);
0304 rdbuf()->swap(*other.rdbuf());
0305 }
0306
0307 void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
0308 {
0309 open(file_name.c_str(), mode);
0310 }
0311 template<typename Path>
0312 detail::enable_if_path_t<Path, void> open(const Path& file_name,
0313 std::ios_base::openmode mode = T_StreamType::mode())
0314 {
0315 open(file_name.c_str(), mode);
0316 }
0317 void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
0318 {
0319 if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
0320 setstate(std::ios_base::failbit);
0321 else
0322 clear();
0323 }
0324 #if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
0325 void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
0326 {
0327 if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
0328 setstate(std::ios_base::failbit);
0329 else
0330 clear();
0331 }
0332 #endif
0333 bool is_open()
0334 {
0335 return rdbuf()->is_open();
0336 }
0337 bool is_open() const
0338 {
0339 return rdbuf()->is_open();
0340 }
0341 void close()
0342 {
0343 if(!rdbuf()->close())
0344 setstate(std::ios_base::failbit);
0345 }
0346
0347 internal_buffer_type* rdbuf() const
0348 {
0349 return const_cast<internal_buffer_type*>(&buf_);
0350 }
0351 };
0352 #ifdef BOOST_MSVC
0353 #pragma warning(pop)
0354 #endif
0355 }
0356 }
0357 }
0358
0359 #endif