1*700637cbSDimitry Andric// -*- C++ -*- 2*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 3*700637cbSDimitry Andric// 4*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*700637cbSDimitry Andric// 8*700637cbSDimitry Andric//===----------------------------------------------------------------------===// 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric#ifndef _LIBCPP___CXX03_FSTREAM 11*700637cbSDimitry Andric#define _LIBCPP___CXX03_FSTREAM 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric/* 14*700637cbSDimitry Andric fstream synopsis 15*700637cbSDimitry Andric 16*700637cbSDimitry Andrictemplate <class charT, class traits = char_traits<charT> > 17*700637cbSDimitry Andricclass basic_filebuf 18*700637cbSDimitry Andric : public basic_streambuf<charT, traits> 19*700637cbSDimitry Andric{ 20*700637cbSDimitry Andricpublic: 21*700637cbSDimitry Andric typedef charT char_type; 22*700637cbSDimitry Andric typedef traits traits_type; 23*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 24*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 25*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 26*700637cbSDimitry Andric 27*700637cbSDimitry Andric // 27.9.1.2 Constructors/destructor: 28*700637cbSDimitry Andric basic_filebuf(); 29*700637cbSDimitry Andric basic_filebuf(basic_filebuf&& rhs); 30*700637cbSDimitry Andric virtual ~basic_filebuf(); 31*700637cbSDimitry Andric 32*700637cbSDimitry Andric // 27.9.1.3 Assign/swap: 33*700637cbSDimitry Andric basic_filebuf& operator=(basic_filebuf&& rhs); 34*700637cbSDimitry Andric void swap(basic_filebuf& rhs); 35*700637cbSDimitry Andric 36*700637cbSDimitry Andric // 27.9.1.4 Members: 37*700637cbSDimitry Andric bool is_open() const; 38*700637cbSDimitry Andric basic_filebuf* open(const char* s, ios_base::openmode mode); 39*700637cbSDimitry Andric basic_filebuf* open(const string& s, ios_base::openmode mode); 40*700637cbSDimitry Andric basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17 41*700637cbSDimitry Andric basic_filebuf* close(); 42*700637cbSDimitry Andric 43*700637cbSDimitry Andricprotected: 44*700637cbSDimitry Andric // 27.9.1.5 Overridden virtual functions: 45*700637cbSDimitry Andric virtual streamsize showmanyc(); 46*700637cbSDimitry Andric virtual int_type underflow(); 47*700637cbSDimitry Andric virtual int_type uflow(); 48*700637cbSDimitry Andric virtual int_type pbackfail(int_type c = traits_type::eof()); 49*700637cbSDimitry Andric virtual int_type overflow (int_type c = traits_type::eof()); 50*700637cbSDimitry Andric virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n); 51*700637cbSDimitry Andric virtual pos_type seekoff(off_type off, ios_base::seekdir way, 52*700637cbSDimitry Andric ios_base::openmode which = ios_base::in | ios_base::out); 53*700637cbSDimitry Andric virtual pos_type seekpos(pos_type sp, 54*700637cbSDimitry Andric ios_base::openmode which = ios_base::in | ios_base::out); 55*700637cbSDimitry Andric virtual int sync(); 56*700637cbSDimitry Andric virtual void imbue(const locale& loc); 57*700637cbSDimitry Andric}; 58*700637cbSDimitry Andric 59*700637cbSDimitry Andrictemplate <class charT, class traits> 60*700637cbSDimitry Andric void 61*700637cbSDimitry Andric swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y); 62*700637cbSDimitry Andric 63*700637cbSDimitry Andrictypedef basic_filebuf<char> filebuf; 64*700637cbSDimitry Andrictypedef basic_filebuf<wchar_t> wfilebuf; 65*700637cbSDimitry Andric 66*700637cbSDimitry Andrictemplate <class charT, class traits = char_traits<charT> > 67*700637cbSDimitry Andricclass basic_ifstream 68*700637cbSDimitry Andric : public basic_istream<charT,traits> 69*700637cbSDimitry Andric{ 70*700637cbSDimitry Andricpublic: 71*700637cbSDimitry Andric typedef charT char_type; 72*700637cbSDimitry Andric typedef traits traits_type; 73*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 74*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 75*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 76*700637cbSDimitry Andric using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26 77*700637cbSDimitry Andric 78*700637cbSDimitry Andric basic_ifstream(); 79*700637cbSDimitry Andric explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); 80*700637cbSDimitry Andric explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); 81*700637cbSDimitry Andric template<class T> 82*700637cbSDimitry Andric explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++17 83*700637cbSDimitry Andric basic_ifstream(basic_ifstream&& rhs); 84*700637cbSDimitry Andric 85*700637cbSDimitry Andric basic_ifstream& operator=(basic_ifstream&& rhs); 86*700637cbSDimitry Andric void swap(basic_ifstream& rhs); 87*700637cbSDimitry Andric 88*700637cbSDimitry Andric basic_filebuf<char_type, traits_type>* rdbuf() const; 89*700637cbSDimitry Andric native_handle_type native_handle() const noexcept; // Since C++26 90*700637cbSDimitry Andric bool is_open() const; 91*700637cbSDimitry Andric void open(const char* s, ios_base::openmode mode = ios_base::in); 92*700637cbSDimitry Andric void open(const string& s, ios_base::openmode mode = ios_base::in); 93*700637cbSDimitry Andric void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17 94*700637cbSDimitry Andric 95*700637cbSDimitry Andric void close(); 96*700637cbSDimitry Andric}; 97*700637cbSDimitry Andric 98*700637cbSDimitry Andrictemplate <class charT, class traits> 99*700637cbSDimitry Andric void 100*700637cbSDimitry Andric swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y); 101*700637cbSDimitry Andric 102*700637cbSDimitry Andrictypedef basic_ifstream<char> ifstream; 103*700637cbSDimitry Andrictypedef basic_ifstream<wchar_t> wifstream; 104*700637cbSDimitry Andric 105*700637cbSDimitry Andrictemplate <class charT, class traits = char_traits<charT> > 106*700637cbSDimitry Andricclass basic_ofstream 107*700637cbSDimitry Andric : public basic_ostream<charT,traits> 108*700637cbSDimitry Andric{ 109*700637cbSDimitry Andricpublic: 110*700637cbSDimitry Andric typedef charT char_type; 111*700637cbSDimitry Andric typedef traits traits_type; 112*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 113*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 114*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 115*700637cbSDimitry Andric using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26 116*700637cbSDimitry Andric 117*700637cbSDimitry Andric basic_ofstream(); 118*700637cbSDimitry Andric explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); 119*700637cbSDimitry Andric explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); 120*700637cbSDimitry Andric template<class T> 121*700637cbSDimitry Andric explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17 122*700637cbSDimitry Andric basic_ofstream(basic_ofstream&& rhs); 123*700637cbSDimitry Andric 124*700637cbSDimitry Andric basic_ofstream& operator=(basic_ofstream&& rhs); 125*700637cbSDimitry Andric void swap(basic_ofstream& rhs); 126*700637cbSDimitry Andric 127*700637cbSDimitry Andric basic_filebuf<char_type, traits_type>* rdbuf() const; 128*700637cbSDimitry Andric native_handle_type native_handle() const noexcept; // Since C++26 129*700637cbSDimitry Andric 130*700637cbSDimitry Andric bool is_open() const; 131*700637cbSDimitry Andric void open(const char* s, ios_base::openmode mode = ios_base::out); 132*700637cbSDimitry Andric void open(const string& s, ios_base::openmode mode = ios_base::out); 133*700637cbSDimitry Andric void open(const filesystem::path& p, 134*700637cbSDimitry Andric ios_base::openmode mode = ios_base::out); // C++17 135*700637cbSDimitry Andric 136*700637cbSDimitry Andric void close(); 137*700637cbSDimitry Andric}; 138*700637cbSDimitry Andric 139*700637cbSDimitry Andrictemplate <class charT, class traits> 140*700637cbSDimitry Andric void 141*700637cbSDimitry Andric swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y); 142*700637cbSDimitry Andric 143*700637cbSDimitry Andrictypedef basic_ofstream<char> ofstream; 144*700637cbSDimitry Andrictypedef basic_ofstream<wchar_t> wofstream; 145*700637cbSDimitry Andric 146*700637cbSDimitry Andrictemplate <class charT, class traits=char_traits<charT> > 147*700637cbSDimitry Andricclass basic_fstream 148*700637cbSDimitry Andric : public basic_iostream<charT,traits> 149*700637cbSDimitry Andric{ 150*700637cbSDimitry Andricpublic: 151*700637cbSDimitry Andric typedef charT char_type; 152*700637cbSDimitry Andric typedef traits traits_type; 153*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 154*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 155*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 156*700637cbSDimitry Andric using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26 157*700637cbSDimitry Andric 158*700637cbSDimitry Andric basic_fstream(); 159*700637cbSDimitry Andric explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); 160*700637cbSDimitry Andric explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); 161*700637cbSDimitry Andric template<class T> 162*700637cbSDimitry Andric explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17 163*700637cbSDimitry Andric basic_fstream(basic_fstream&& rhs); 164*700637cbSDimitry Andric 165*700637cbSDimitry Andric basic_fstream& operator=(basic_fstream&& rhs); 166*700637cbSDimitry Andric void swap(basic_fstream& rhs); 167*700637cbSDimitry Andric 168*700637cbSDimitry Andric basic_filebuf<char_type, traits_type>* rdbuf() const; 169*700637cbSDimitry Andric native_handle_type native_handle() const noexcept; // Since C++26 170*700637cbSDimitry Andric bool is_open() const; 171*700637cbSDimitry Andric void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); 172*700637cbSDimitry Andric void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); 173*700637cbSDimitry Andric void open(const filesystem::path& s, 174*700637cbSDimitry Andric ios_base::openmode mode = ios_base::in|ios_base::out); // C++17 175*700637cbSDimitry Andric 176*700637cbSDimitry Andric void close(); 177*700637cbSDimitry Andric}; 178*700637cbSDimitry Andric 179*700637cbSDimitry Andrictemplate <class charT, class traits> 180*700637cbSDimitry Andric void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y); 181*700637cbSDimitry Andric 182*700637cbSDimitry Andrictypedef basic_fstream<char> fstream; 183*700637cbSDimitry Andrictypedef basic_fstream<wchar_t> wfstream; 184*700637cbSDimitry Andric 185*700637cbSDimitry Andric} // std 186*700637cbSDimitry Andric 187*700637cbSDimitry Andric*/ 188*700637cbSDimitry Andric 189*700637cbSDimitry Andric#include <__cxx03/__algorithm/max.h> 190*700637cbSDimitry Andric#include <__cxx03/__assert> 191*700637cbSDimitry Andric#include <__cxx03/__config> 192*700637cbSDimitry Andric#include <__cxx03/__fwd/fstream.h> 193*700637cbSDimitry Andric#include <__cxx03/__locale> 194*700637cbSDimitry Andric#include <__cxx03/__type_traits/enable_if.h> 195*700637cbSDimitry Andric#include <__cxx03/__type_traits/is_same.h> 196*700637cbSDimitry Andric#include <__cxx03/__utility/move.h> 197*700637cbSDimitry Andric#include <__cxx03/__utility/swap.h> 198*700637cbSDimitry Andric#include <__cxx03/__utility/unreachable.h> 199*700637cbSDimitry Andric#include <__cxx03/cstdio> 200*700637cbSDimitry Andric#include <__cxx03/istream> 201*700637cbSDimitry Andric#include <__cxx03/ostream> 202*700637cbSDimitry Andric#include <__cxx03/typeinfo> 203*700637cbSDimitry Andric#include <__cxx03/version> 204*700637cbSDimitry Andric 205*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 206*700637cbSDimitry Andric# pragma GCC system_header 207*700637cbSDimitry Andric#endif 208*700637cbSDimitry Andric 209*700637cbSDimitry Andric_LIBCPP_PUSH_MACROS 210*700637cbSDimitry Andric#include <__cxx03/__undef_macros> 211*700637cbSDimitry Andric 212*700637cbSDimitry Andric#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) 213*700637cbSDimitry Andric# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS 214*700637cbSDimitry Andric#endif 215*700637cbSDimitry Andric 216*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_FILESYSTEM) 217*700637cbSDimitry Andric 218*700637cbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 219*700637cbSDimitry Andric 220*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 221*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> { 222*700637cbSDimitry Andricpublic: 223*700637cbSDimitry Andric typedef _CharT char_type; 224*700637cbSDimitry Andric typedef _Traits traits_type; 225*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 226*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 227*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 228*700637cbSDimitry Andric typedef typename traits_type::state_type state_type; 229*700637cbSDimitry Andric 230*700637cbSDimitry Andric // 27.9.1.2 Constructors/destructor: 231*700637cbSDimitry Andric basic_filebuf(); 232*700637cbSDimitry Andric basic_filebuf(basic_filebuf&& __rhs); 233*700637cbSDimitry Andric ~basic_filebuf() override; 234*700637cbSDimitry Andric 235*700637cbSDimitry Andric // 27.9.1.3 Assign/swap: 236*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs); 237*700637cbSDimitry Andric void swap(basic_filebuf& __rhs); 238*700637cbSDimitry Andric 239*700637cbSDimitry Andric // 27.9.1.4 Members: 240*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_open() const; 241*700637cbSDimitry Andric basic_filebuf* open(const char* __s, ios_base::openmode __mode); 242*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 243*700637cbSDimitry Andric basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode); 244*700637cbSDimitry Andric# endif 245*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode); 246*700637cbSDimitry Andric 247*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode); 248*700637cbSDimitry Andric basic_filebuf* close(); 249*700637cbSDimitry Andric 250*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT; 251*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 252*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT; 253*700637cbSDimitry Andric# endif 254*700637cbSDimitry Andric 255*700637cbSDimitry Andricprotected: 256*700637cbSDimitry Andric // 27.9.1.5 Overridden virtual functions: 257*700637cbSDimitry Andric int_type underflow() override; 258*700637cbSDimitry Andric int_type pbackfail(int_type __c = traits_type::eof()) override; 259*700637cbSDimitry Andric int_type overflow(int_type __c = traits_type::eof()) override; 260*700637cbSDimitry Andric basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override; 261*700637cbSDimitry Andric pos_type 262*700637cbSDimitry Andric seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override; 263*700637cbSDimitry Andric pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override; 264*700637cbSDimitry Andric int sync() override; 265*700637cbSDimitry Andric void imbue(const locale& __loc) override; 266*700637cbSDimitry Andric 267*700637cbSDimitry Andricprivate: 268*700637cbSDimitry Andric char* __extbuf_; 269*700637cbSDimitry Andric const char* __extbufnext_; 270*700637cbSDimitry Andric const char* __extbufend_; 271*700637cbSDimitry Andric char __extbuf_min_[8]; 272*700637cbSDimitry Andric size_t __ebs_; 273*700637cbSDimitry Andric char_type* __intbuf_; 274*700637cbSDimitry Andric size_t __ibs_; 275*700637cbSDimitry Andric FILE* __file_; 276*700637cbSDimitry Andric const codecvt<char_type, char, state_type>* __cv_; 277*700637cbSDimitry Andric state_type __st_; 278*700637cbSDimitry Andric state_type __st_last_; 279*700637cbSDimitry Andric ios_base::openmode __om_; 280*700637cbSDimitry Andric // There have been no file operations yet, which allows setting unbuffered 281*700637cbSDimitry Andric // I/O mode. 282*700637cbSDimitry Andric static const ios_base::openmode __no_io_operations = ios_base::trunc; 283*700637cbSDimitry Andric // Unbuffered I/O mode has been requested. 284*700637cbSDimitry Andric static const ios_base::openmode __use_unbuffered_io = ios_base::ate; 285*700637cbSDimitry Andric // Used to track the currently used mode and track whether the output should 286*700637cbSDimitry Andric // be unbuffered. 287*700637cbSDimitry Andric // [filebuf.virtuals]/12 288*700637cbSDimitry Andric // If setbuf(0, 0) is called on a stream before any I/O has occurred on 289*700637cbSDimitry Andric // that stream, the stream becomes unbuffered. Otherwise the results are 290*700637cbSDimitry Andric // implementation-defined. 291*700637cbSDimitry Andric // This allows calling setbuf(0, 0) 292*700637cbSDimitry Andric // - before opening a file, 293*700637cbSDimitry Andric // - after opening a file, before 294*700637cbSDimitry Andric // - a read 295*700637cbSDimitry Andric // - a write 296*700637cbSDimitry Andric // - a seek. 297*700637cbSDimitry Andric // Note that opening a file with ios_base::ate does a seek operation. 298*700637cbSDimitry Andric // Normally underflow, overflow, and sync change this flag to ios_base::in, 299*700637cbSDimitry Andric // ios_base_out, or 0. 300*700637cbSDimitry Andric // 301*700637cbSDimitry Andric // The ios_base::trunc and ios_base::ate flags are not used in __cm_. They 302*700637cbSDimitry Andric // are used to track the state of the unbuffered request. For readability 303*700637cbSDimitry Andric // they have the aliases __no_io_operations and __use_unbuffered_io 304*700637cbSDimitry Andric // respectively. 305*700637cbSDimitry Andric // 306*700637cbSDimitry Andric // The __no_io_operations and __use_unbuffered_io flags are used in the 307*700637cbSDimitry Andric // following way: 308*700637cbSDimitry Andric // - __no_io_operations is set upon construction to indicate the unbuffered 309*700637cbSDimitry Andric // state can be set. 310*700637cbSDimitry Andric // - When requesting unbuffered output: 311*700637cbSDimitry Andric // - If the file is open it sets the mode. 312*700637cbSDimitry Andric // - Else places a request by adding the __use_unbuffered_io flag. 313*700637cbSDimitry Andric // - When a file is opened it checks whether both __no_io_operations and 314*700637cbSDimitry Andric // __use_unbuffered_io are set. If so switches to unbuffered mode. 315*700637cbSDimitry Andric // - All file I/O operations change the mode effectively clearing the 316*700637cbSDimitry Andric // __no_io_operations and __use_unbuffered_io flags. 317*700637cbSDimitry Andric ios_base::openmode __cm_; 318*700637cbSDimitry Andric bool __owns_eb_; 319*700637cbSDimitry Andric bool __owns_ib_; 320*700637cbSDimitry Andric bool __always_noconv_; 321*700637cbSDimitry Andric 322*700637cbSDimitry Andric bool __read_mode(); 323*700637cbSDimitry Andric void __write_mode(); 324*700637cbSDimitry Andric 325*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&); 326*700637cbSDimitry Andric 327*700637cbSDimitry Andric // There are multiple (__)open function, they use different C-API open 328*700637cbSDimitry Andric // function. After that call these functions behave the same. This function 329*700637cbSDimitry Andric // does that part and determines the final return value. 330*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) { 331*700637cbSDimitry Andric __file_ = __file; 332*700637cbSDimitry Andric if (!__file_) 333*700637cbSDimitry Andric return nullptr; 334*700637cbSDimitry Andric 335*700637cbSDimitry Andric __om_ = __mode; 336*700637cbSDimitry Andric if (__cm_ == (__no_io_operations | __use_unbuffered_io)) { 337*700637cbSDimitry Andric std::setbuf(__file_, nullptr); 338*700637cbSDimitry Andric __cm_ = 0; 339*700637cbSDimitry Andric } 340*700637cbSDimitry Andric 341*700637cbSDimitry Andric if (__mode & ios_base::ate) { 342*700637cbSDimitry Andric __cm_ = 0; 343*700637cbSDimitry Andric if (fseek(__file_, 0, SEEK_END)) { 344*700637cbSDimitry Andric fclose(__file_); 345*700637cbSDimitry Andric __file_ = nullptr; 346*700637cbSDimitry Andric return nullptr; 347*700637cbSDimitry Andric } 348*700637cbSDimitry Andric } 349*700637cbSDimitry Andric 350*700637cbSDimitry Andric return this; 351*700637cbSDimitry Andric } 352*700637cbSDimitry Andric 353*700637cbSDimitry Andric // If the file is already open, switch to unbuffered mode. Otherwise, record 354*700637cbSDimitry Andric // the request to use unbuffered mode so that we use that mode when we 355*700637cbSDimitry Andric // eventually open the file. 356*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode(char_type* __s, streamsize __n) { 357*700637cbSDimitry Andric if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) { 358*700637cbSDimitry Andric if (__file_) { 359*700637cbSDimitry Andric std::setbuf(__file_, nullptr); 360*700637cbSDimitry Andric __cm_ = 0; 361*700637cbSDimitry Andric } else { 362*700637cbSDimitry Andric __cm_ = __no_io_operations | __use_unbuffered_io; 363*700637cbSDimitry Andric } 364*700637cbSDimitry Andric } 365*700637cbSDimitry Andric } 366*700637cbSDimitry Andric}; 367*700637cbSDimitry Andric 368*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 369*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf() 370*700637cbSDimitry Andric : __extbuf_(nullptr), 371*700637cbSDimitry Andric __extbufnext_(nullptr), 372*700637cbSDimitry Andric __extbufend_(nullptr), 373*700637cbSDimitry Andric __ebs_(0), 374*700637cbSDimitry Andric __intbuf_(nullptr), 375*700637cbSDimitry Andric __ibs_(0), 376*700637cbSDimitry Andric __file_(nullptr), 377*700637cbSDimitry Andric __cv_(nullptr), 378*700637cbSDimitry Andric __st_(), 379*700637cbSDimitry Andric __st_last_(), 380*700637cbSDimitry Andric __om_(0), 381*700637cbSDimitry Andric __cm_(__no_io_operations), 382*700637cbSDimitry Andric __owns_eb_(false), 383*700637cbSDimitry Andric __owns_ib_(false), 384*700637cbSDimitry Andric __always_noconv_(false) { 385*700637cbSDimitry Andric if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) { 386*700637cbSDimitry Andric __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc()); 387*700637cbSDimitry Andric __always_noconv_ = __cv_->always_noconv(); 388*700637cbSDimitry Andric } 389*700637cbSDimitry Andric setbuf(nullptr, 4096); 390*700637cbSDimitry Andric} 391*700637cbSDimitry Andric 392*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 393*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) { 394*700637cbSDimitry Andric if (__rhs.__extbuf_ == __rhs.__extbuf_min_) { 395*700637cbSDimitry Andric __extbuf_ = __extbuf_min_; 396*700637cbSDimitry Andric __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_); 397*700637cbSDimitry Andric __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_); 398*700637cbSDimitry Andric } else { 399*700637cbSDimitry Andric __extbuf_ = __rhs.__extbuf_; 400*700637cbSDimitry Andric __extbufnext_ = __rhs.__extbufnext_; 401*700637cbSDimitry Andric __extbufend_ = __rhs.__extbufend_; 402*700637cbSDimitry Andric } 403*700637cbSDimitry Andric __ebs_ = __rhs.__ebs_; 404*700637cbSDimitry Andric __intbuf_ = __rhs.__intbuf_; 405*700637cbSDimitry Andric __ibs_ = __rhs.__ibs_; 406*700637cbSDimitry Andric __file_ = __rhs.__file_; 407*700637cbSDimitry Andric __cv_ = __rhs.__cv_; 408*700637cbSDimitry Andric __st_ = __rhs.__st_; 409*700637cbSDimitry Andric __st_last_ = __rhs.__st_last_; 410*700637cbSDimitry Andric __om_ = __rhs.__om_; 411*700637cbSDimitry Andric __cm_ = __rhs.__cm_; 412*700637cbSDimitry Andric __owns_eb_ = __rhs.__owns_eb_; 413*700637cbSDimitry Andric __owns_ib_ = __rhs.__owns_ib_; 414*700637cbSDimitry Andric __always_noconv_ = __rhs.__always_noconv_; 415*700637cbSDimitry Andric if (__rhs.pbase()) { 416*700637cbSDimitry Andric if (__rhs.pbase() == __rhs.__intbuf_) 417*700637cbSDimitry Andric this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase())); 418*700637cbSDimitry Andric else 419*700637cbSDimitry Andric this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase())); 420*700637cbSDimitry Andric this->__pbump(__rhs.pptr() - __rhs.pbase()); 421*700637cbSDimitry Andric } else if (__rhs.eback()) { 422*700637cbSDimitry Andric if (__rhs.eback() == __rhs.__intbuf_) 423*700637cbSDimitry Andric this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback())); 424*700637cbSDimitry Andric else 425*700637cbSDimitry Andric this->setg((char_type*)__extbuf_, 426*700637cbSDimitry Andric (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()), 427*700637cbSDimitry Andric (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback())); 428*700637cbSDimitry Andric } 429*700637cbSDimitry Andric __rhs.__extbuf_ = nullptr; 430*700637cbSDimitry Andric __rhs.__extbufnext_ = nullptr; 431*700637cbSDimitry Andric __rhs.__extbufend_ = nullptr; 432*700637cbSDimitry Andric __rhs.__ebs_ = 0; 433*700637cbSDimitry Andric __rhs.__intbuf_ = 0; 434*700637cbSDimitry Andric __rhs.__ibs_ = 0; 435*700637cbSDimitry Andric __rhs.__file_ = nullptr; 436*700637cbSDimitry Andric __rhs.__st_ = state_type(); 437*700637cbSDimitry Andric __rhs.__st_last_ = state_type(); 438*700637cbSDimitry Andric __rhs.__om_ = 0; 439*700637cbSDimitry Andric __rhs.__cm_ = 0; 440*700637cbSDimitry Andric __rhs.__owns_eb_ = false; 441*700637cbSDimitry Andric __rhs.__owns_ib_ = false; 442*700637cbSDimitry Andric __rhs.setg(0, 0, 0); 443*700637cbSDimitry Andric __rhs.setp(0, 0); 444*700637cbSDimitry Andric} 445*700637cbSDimitry Andric 446*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 447*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) { 448*700637cbSDimitry Andric close(); 449*700637cbSDimitry Andric swap(__rhs); 450*700637cbSDimitry Andric return *this; 451*700637cbSDimitry Andric} 452*700637cbSDimitry Andric 453*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 454*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::~basic_filebuf() { 455*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 456*700637cbSDimitry Andric try { 457*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 458*700637cbSDimitry Andric close(); 459*700637cbSDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 460*700637cbSDimitry Andric } catch (...) { 461*700637cbSDimitry Andric } 462*700637cbSDimitry Andric# endif // _LIBCPP_HAS_NO_EXCEPTIONS 463*700637cbSDimitry Andric if (__owns_eb_) 464*700637cbSDimitry Andric delete[] __extbuf_; 465*700637cbSDimitry Andric if (__owns_ib_) 466*700637cbSDimitry Andric delete[] __intbuf_; 467*700637cbSDimitry Andric} 468*700637cbSDimitry Andric 469*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 470*700637cbSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) { 471*700637cbSDimitry Andric basic_streambuf<char_type, traits_type>::swap(__rhs); 472*700637cbSDimitry Andric if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) { 473*700637cbSDimitry Andric // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers. 474*700637cbSDimitry Andric std::swap(__extbuf_, __rhs.__extbuf_); 475*700637cbSDimitry Andric std::swap(__extbufnext_, __rhs.__extbufnext_); 476*700637cbSDimitry Andric std::swap(__extbufend_, __rhs.__extbufend_); 477*700637cbSDimitry Andric } else { 478*700637cbSDimitry Andric ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0; 479*700637cbSDimitry Andric ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0; 480*700637cbSDimitry Andric ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0; 481*700637cbSDimitry Andric ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0; 482*700637cbSDimitry Andric if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) { 483*700637cbSDimitry Andric // *this uses the small buffer, but __rhs doesn't. 484*700637cbSDimitry Andric __extbuf_ = __rhs.__extbuf_; 485*700637cbSDimitry Andric __rhs.__extbuf_ = __rhs.__extbuf_min_; 486*700637cbSDimitry Andric std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_)); 487*700637cbSDimitry Andric } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) { 488*700637cbSDimitry Andric // *this doesn't use the small buffer, but __rhs does. 489*700637cbSDimitry Andric __rhs.__extbuf_ = __extbuf_; 490*700637cbSDimitry Andric __extbuf_ = __extbuf_min_; 491*700637cbSDimitry Andric std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_)); 492*700637cbSDimitry Andric } else { 493*700637cbSDimitry Andric // Both *this and __rhs use the small buffer. 494*700637cbSDimitry Andric char __tmp[sizeof(__extbuf_min_)]; 495*700637cbSDimitry Andric std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_)); 496*700637cbSDimitry Andric std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_)); 497*700637cbSDimitry Andric std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_)); 498*700637cbSDimitry Andric } 499*700637cbSDimitry Andric __extbufnext_ = __extbuf_ + __rn; 500*700637cbSDimitry Andric __extbufend_ = __extbuf_ + __re; 501*700637cbSDimitry Andric __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln; 502*700637cbSDimitry Andric __rhs.__extbufend_ = __rhs.__extbuf_ + __le; 503*700637cbSDimitry Andric } 504*700637cbSDimitry Andric std::swap(__ebs_, __rhs.__ebs_); 505*700637cbSDimitry Andric std::swap(__intbuf_, __rhs.__intbuf_); 506*700637cbSDimitry Andric std::swap(__ibs_, __rhs.__ibs_); 507*700637cbSDimitry Andric std::swap(__file_, __rhs.__file_); 508*700637cbSDimitry Andric std::swap(__cv_, __rhs.__cv_); 509*700637cbSDimitry Andric std::swap(__st_, __rhs.__st_); 510*700637cbSDimitry Andric std::swap(__st_last_, __rhs.__st_last_); 511*700637cbSDimitry Andric std::swap(__om_, __rhs.__om_); 512*700637cbSDimitry Andric std::swap(__cm_, __rhs.__cm_); 513*700637cbSDimitry Andric std::swap(__owns_eb_, __rhs.__owns_eb_); 514*700637cbSDimitry Andric std::swap(__owns_ib_, __rhs.__owns_ib_); 515*700637cbSDimitry Andric std::swap(__always_noconv_, __rhs.__always_noconv_); 516*700637cbSDimitry Andric if (this->eback() == (char_type*)__rhs.__extbuf_min_) { 517*700637cbSDimitry Andric ptrdiff_t __n = this->gptr() - this->eback(); 518*700637cbSDimitry Andric ptrdiff_t __e = this->egptr() - this->eback(); 519*700637cbSDimitry Andric this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e); 520*700637cbSDimitry Andric } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) { 521*700637cbSDimitry Andric ptrdiff_t __n = this->pptr() - this->pbase(); 522*700637cbSDimitry Andric ptrdiff_t __e = this->epptr() - this->pbase(); 523*700637cbSDimitry Andric this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e); 524*700637cbSDimitry Andric this->__pbump(__n); 525*700637cbSDimitry Andric } 526*700637cbSDimitry Andric if (__rhs.eback() == (char_type*)__extbuf_min_) { 527*700637cbSDimitry Andric ptrdiff_t __n = __rhs.gptr() - __rhs.eback(); 528*700637cbSDimitry Andric ptrdiff_t __e = __rhs.egptr() - __rhs.eback(); 529*700637cbSDimitry Andric __rhs.setg( 530*700637cbSDimitry Andric (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e); 531*700637cbSDimitry Andric } else if (__rhs.pbase() == (char_type*)__extbuf_min_) { 532*700637cbSDimitry Andric ptrdiff_t __n = __rhs.pptr() - __rhs.pbase(); 533*700637cbSDimitry Andric ptrdiff_t __e = __rhs.epptr() - __rhs.pbase(); 534*700637cbSDimitry Andric __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e); 535*700637cbSDimitry Andric __rhs.__pbump(__n); 536*700637cbSDimitry Andric } 537*700637cbSDimitry Andric} 538*700637cbSDimitry Andric 539*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 540*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) { 541*700637cbSDimitry Andric __x.swap(__y); 542*700637cbSDimitry Andric} 543*700637cbSDimitry Andric 544*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 545*700637cbSDimitry Andricinline bool basic_filebuf<_CharT, _Traits>::is_open() const { 546*700637cbSDimitry Andric return __file_ != nullptr; 547*700637cbSDimitry Andric} 548*700637cbSDimitry Andric 549*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 550*700637cbSDimitry Andricconst char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT { 551*700637cbSDimitry Andric switch (__mode & ~ios_base::ate) { 552*700637cbSDimitry Andric case ios_base::out: 553*700637cbSDimitry Andric case ios_base::out | ios_base::trunc: 554*700637cbSDimitry Andric return "w" _LIBCPP_FOPEN_CLOEXEC_MODE; 555*700637cbSDimitry Andric case ios_base::out | ios_base::app: 556*700637cbSDimitry Andric case ios_base::app: 557*700637cbSDimitry Andric return "a" _LIBCPP_FOPEN_CLOEXEC_MODE; 558*700637cbSDimitry Andric case ios_base::in: 559*700637cbSDimitry Andric return "r" _LIBCPP_FOPEN_CLOEXEC_MODE; 560*700637cbSDimitry Andric case ios_base::in | ios_base::out: 561*700637cbSDimitry Andric return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE; 562*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::trunc: 563*700637cbSDimitry Andric return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE; 564*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::app: 565*700637cbSDimitry Andric case ios_base::in | ios_base::app: 566*700637cbSDimitry Andric return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE; 567*700637cbSDimitry Andric case ios_base::out | ios_base::binary: 568*700637cbSDimitry Andric case ios_base::out | ios_base::trunc | ios_base::binary: 569*700637cbSDimitry Andric return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE; 570*700637cbSDimitry Andric case ios_base::out | ios_base::app | ios_base::binary: 571*700637cbSDimitry Andric case ios_base::app | ios_base::binary: 572*700637cbSDimitry Andric return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE; 573*700637cbSDimitry Andric case ios_base::in | ios_base::binary: 574*700637cbSDimitry Andric return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE; 575*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::binary: 576*700637cbSDimitry Andric return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE; 577*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: 578*700637cbSDimitry Andric return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE; 579*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: 580*700637cbSDimitry Andric case ios_base::in | ios_base::app | ios_base::binary: 581*700637cbSDimitry Andric return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE; 582*700637cbSDimitry Andric default: 583*700637cbSDimitry Andric return nullptr; 584*700637cbSDimitry Andric } 585*700637cbSDimitry Andric __libcpp_unreachable(); 586*700637cbSDimitry Andric} 587*700637cbSDimitry Andric 588*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 589*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 590*700637cbSDimitry Andricconst wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT { 591*700637cbSDimitry Andric switch (__mode & ~ios_base::ate) { 592*700637cbSDimitry Andric case ios_base::out: 593*700637cbSDimitry Andric case ios_base::out | ios_base::trunc: 594*700637cbSDimitry Andric return L"w"; 595*700637cbSDimitry Andric case ios_base::out | ios_base::app: 596*700637cbSDimitry Andric case ios_base::app: 597*700637cbSDimitry Andric return L"a"; 598*700637cbSDimitry Andric case ios_base::in: 599*700637cbSDimitry Andric return L"r"; 600*700637cbSDimitry Andric case ios_base::in | ios_base::out: 601*700637cbSDimitry Andric return L"r+"; 602*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::trunc: 603*700637cbSDimitry Andric return L"w+"; 604*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::app: 605*700637cbSDimitry Andric case ios_base::in | ios_base::app: 606*700637cbSDimitry Andric return L"a+"; 607*700637cbSDimitry Andric case ios_base::out | ios_base::binary: 608*700637cbSDimitry Andric case ios_base::out | ios_base::trunc | ios_base::binary: 609*700637cbSDimitry Andric return L"wb"; 610*700637cbSDimitry Andric case ios_base::out | ios_base::app | ios_base::binary: 611*700637cbSDimitry Andric case ios_base::app | ios_base::binary: 612*700637cbSDimitry Andric return L"ab"; 613*700637cbSDimitry Andric case ios_base::in | ios_base::binary: 614*700637cbSDimitry Andric return L"rb"; 615*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::binary: 616*700637cbSDimitry Andric return L"r+b"; 617*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: 618*700637cbSDimitry Andric return L"w+b"; 619*700637cbSDimitry Andric case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: 620*700637cbSDimitry Andric case ios_base::in | ios_base::app | ios_base::binary: 621*700637cbSDimitry Andric return L"a+b"; 622*700637cbSDimitry Andric default: 623*700637cbSDimitry Andric return nullptr; 624*700637cbSDimitry Andric } 625*700637cbSDimitry Andric __libcpp_unreachable(); 626*700637cbSDimitry Andric} 627*700637cbSDimitry Andric# endif 628*700637cbSDimitry Andric 629*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 630*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) { 631*700637cbSDimitry Andric if (__file_) 632*700637cbSDimitry Andric return nullptr; 633*700637cbSDimitry Andric const char* __mdstr = __make_mdstring(__mode); 634*700637cbSDimitry Andric if (!__mdstr) 635*700637cbSDimitry Andric return nullptr; 636*700637cbSDimitry Andric 637*700637cbSDimitry Andric return __do_open(fopen(__s, __mdstr), __mode); 638*700637cbSDimitry Andric} 639*700637cbSDimitry Andric 640*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 641*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) { 642*700637cbSDimitry Andric if (__file_) 643*700637cbSDimitry Andric return nullptr; 644*700637cbSDimitry Andric const char* __mdstr = __make_mdstring(__mode); 645*700637cbSDimitry Andric if (!__mdstr) 646*700637cbSDimitry Andric return nullptr; 647*700637cbSDimitry Andric 648*700637cbSDimitry Andric return __do_open(fdopen(__fd, __mdstr), __mode); 649*700637cbSDimitry Andric} 650*700637cbSDimitry Andric 651*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 652*700637cbSDimitry Andric// This is basically the same as the char* overload except that it uses _wfopen 653*700637cbSDimitry Andric// and long mode strings. 654*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 655*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) { 656*700637cbSDimitry Andric if (__file_) 657*700637cbSDimitry Andric return nullptr; 658*700637cbSDimitry Andric const wchar_t* __mdstr = __make_mdwstring(__mode); 659*700637cbSDimitry Andric if (!__mdstr) 660*700637cbSDimitry Andric return nullptr; 661*700637cbSDimitry Andric 662*700637cbSDimitry Andric return __do_open(_wfopen(__s, __mdstr), __mode); 663*700637cbSDimitry Andric} 664*700637cbSDimitry Andric# endif 665*700637cbSDimitry Andric 666*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 667*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>* 668*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { 669*700637cbSDimitry Andric return open(__s.c_str(), __mode); 670*700637cbSDimitry Andric} 671*700637cbSDimitry Andric 672*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 673*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() { 674*700637cbSDimitry Andric basic_filebuf<_CharT, _Traits>* __rt = nullptr; 675*700637cbSDimitry Andric if (__file_) { 676*700637cbSDimitry Andric __rt = this; 677*700637cbSDimitry Andric unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose); 678*700637cbSDimitry Andric if (sync()) 679*700637cbSDimitry Andric __rt = nullptr; 680*700637cbSDimitry Andric if (fclose(__h.release())) 681*700637cbSDimitry Andric __rt = nullptr; 682*700637cbSDimitry Andric __file_ = nullptr; 683*700637cbSDimitry Andric setbuf(0, 0); 684*700637cbSDimitry Andric } 685*700637cbSDimitry Andric return __rt; 686*700637cbSDimitry Andric} 687*700637cbSDimitry Andric 688*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 689*700637cbSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() { 690*700637cbSDimitry Andric if (__file_ == nullptr) 691*700637cbSDimitry Andric return traits_type::eof(); 692*700637cbSDimitry Andric bool __initial = __read_mode(); 693*700637cbSDimitry Andric char_type __1buf; 694*700637cbSDimitry Andric if (this->gptr() == nullptr) 695*700637cbSDimitry Andric this->setg(&__1buf, &__1buf + 1, &__1buf + 1); 696*700637cbSDimitry Andric const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4); 697*700637cbSDimitry Andric int_type __c = traits_type::eof(); 698*700637cbSDimitry Andric if (this->gptr() == this->egptr()) { 699*700637cbSDimitry Andric std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 700*700637cbSDimitry Andric if (__always_noconv_) { 701*700637cbSDimitry Andric size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz); 702*700637cbSDimitry Andric __nmemb = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_); 703*700637cbSDimitry Andric if (__nmemb != 0) { 704*700637cbSDimitry Andric this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb); 705*700637cbSDimitry Andric __c = traits_type::to_int_type(*this->gptr()); 706*700637cbSDimitry Andric } 707*700637cbSDimitry Andric } else { 708*700637cbSDimitry Andric if (__extbufend_ != __extbufnext_) { 709*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr"); 710*700637cbSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr"); 711*700637cbSDimitry Andric std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 712*700637cbSDimitry Andric } 713*700637cbSDimitry Andric __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 714*700637cbSDimitry Andric __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 715*700637cbSDimitry Andric size_t __nmemb = 716*700637cbSDimitry Andric std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_)); 717*700637cbSDimitry Andric codecvt_base::result __r; 718*700637cbSDimitry Andric __st_last_ = __st_; 719*700637cbSDimitry Andric size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_); 720*700637cbSDimitry Andric if (__nr != 0) { 721*700637cbSDimitry Andric if (!__cv_) 722*700637cbSDimitry Andric __throw_bad_cast(); 723*700637cbSDimitry Andric 724*700637cbSDimitry Andric __extbufend_ = __extbufnext_ + __nr; 725*700637cbSDimitry Andric char_type* __inext; 726*700637cbSDimitry Andric __r = __cv_->in( 727*700637cbSDimitry Andric __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext); 728*700637cbSDimitry Andric if (__r == codecvt_base::noconv) { 729*700637cbSDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_)); 730*700637cbSDimitry Andric __c = traits_type::to_int_type(*this->gptr()); 731*700637cbSDimitry Andric } else if (__inext != this->eback() + __unget_sz) { 732*700637cbSDimitry Andric this->setg(this->eback(), this->eback() + __unget_sz, __inext); 733*700637cbSDimitry Andric __c = traits_type::to_int_type(*this->gptr()); 734*700637cbSDimitry Andric } 735*700637cbSDimitry Andric } 736*700637cbSDimitry Andric } 737*700637cbSDimitry Andric } else 738*700637cbSDimitry Andric __c = traits_type::to_int_type(*this->gptr()); 739*700637cbSDimitry Andric if (this->eback() == &__1buf) 740*700637cbSDimitry Andric this->setg(nullptr, nullptr, nullptr); 741*700637cbSDimitry Andric return __c; 742*700637cbSDimitry Andric} 743*700637cbSDimitry Andric 744*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 745*700637cbSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) { 746*700637cbSDimitry Andric if (__file_ && this->eback() < this->gptr()) { 747*700637cbSDimitry Andric if (traits_type::eq_int_type(__c, traits_type::eof())) { 748*700637cbSDimitry Andric this->gbump(-1); 749*700637cbSDimitry Andric return traits_type::not_eof(__c); 750*700637cbSDimitry Andric } 751*700637cbSDimitry Andric if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) { 752*700637cbSDimitry Andric this->gbump(-1); 753*700637cbSDimitry Andric *this->gptr() = traits_type::to_char_type(__c); 754*700637cbSDimitry Andric return __c; 755*700637cbSDimitry Andric } 756*700637cbSDimitry Andric } 757*700637cbSDimitry Andric return traits_type::eof(); 758*700637cbSDimitry Andric} 759*700637cbSDimitry Andric 760*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 761*700637cbSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) { 762*700637cbSDimitry Andric if (__file_ == nullptr) 763*700637cbSDimitry Andric return traits_type::eof(); 764*700637cbSDimitry Andric __write_mode(); 765*700637cbSDimitry Andric char_type __1buf; 766*700637cbSDimitry Andric char_type* __pb_save = this->pbase(); 767*700637cbSDimitry Andric char_type* __epb_save = this->epptr(); 768*700637cbSDimitry Andric if (!traits_type::eq_int_type(__c, traits_type::eof())) { 769*700637cbSDimitry Andric if (this->pptr() == nullptr) 770*700637cbSDimitry Andric this->setp(&__1buf, &__1buf + 1); 771*700637cbSDimitry Andric *this->pptr() = traits_type::to_char_type(__c); 772*700637cbSDimitry Andric this->pbump(1); 773*700637cbSDimitry Andric } 774*700637cbSDimitry Andric if (this->pptr() != this->pbase()) { 775*700637cbSDimitry Andric if (__always_noconv_) { 776*700637cbSDimitry Andric size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 777*700637cbSDimitry Andric if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb) 778*700637cbSDimitry Andric return traits_type::eof(); 779*700637cbSDimitry Andric } else { 780*700637cbSDimitry Andric char* __extbe = __extbuf_; 781*700637cbSDimitry Andric codecvt_base::result __r; 782*700637cbSDimitry Andric do { 783*700637cbSDimitry Andric if (!__cv_) 784*700637cbSDimitry Andric __throw_bad_cast(); 785*700637cbSDimitry Andric 786*700637cbSDimitry Andric const char_type* __e; 787*700637cbSDimitry Andric __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe); 788*700637cbSDimitry Andric if (__e == this->pbase()) 789*700637cbSDimitry Andric return traits_type::eof(); 790*700637cbSDimitry Andric if (__r == codecvt_base::noconv) { 791*700637cbSDimitry Andric size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 792*700637cbSDimitry Andric if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb) 793*700637cbSDimitry Andric return traits_type::eof(); 794*700637cbSDimitry Andric } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) { 795*700637cbSDimitry Andric size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_); 796*700637cbSDimitry Andric if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) 797*700637cbSDimitry Andric return traits_type::eof(); 798*700637cbSDimitry Andric if (__r == codecvt_base::partial) { 799*700637cbSDimitry Andric this->setp(const_cast<char_type*>(__e), this->pptr()); 800*700637cbSDimitry Andric this->__pbump(this->epptr() - this->pbase()); 801*700637cbSDimitry Andric } 802*700637cbSDimitry Andric } else 803*700637cbSDimitry Andric return traits_type::eof(); 804*700637cbSDimitry Andric } while (__r == codecvt_base::partial); 805*700637cbSDimitry Andric } 806*700637cbSDimitry Andric this->setp(__pb_save, __epb_save); 807*700637cbSDimitry Andric } 808*700637cbSDimitry Andric return traits_type::not_eof(__c); 809*700637cbSDimitry Andric} 810*700637cbSDimitry Andric 811*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 812*700637cbSDimitry Andricbasic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) { 813*700637cbSDimitry Andric this->setg(nullptr, nullptr, nullptr); 814*700637cbSDimitry Andric this->setp(nullptr, nullptr); 815*700637cbSDimitry Andric __request_unbuffered_mode(__s, __n); 816*700637cbSDimitry Andric if (__owns_eb_) 817*700637cbSDimitry Andric delete[] __extbuf_; 818*700637cbSDimitry Andric if (__owns_ib_) 819*700637cbSDimitry Andric delete[] __intbuf_; 820*700637cbSDimitry Andric __ebs_ = __n; 821*700637cbSDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) { 822*700637cbSDimitry Andric if (__always_noconv_ && __s) { 823*700637cbSDimitry Andric __extbuf_ = (char*)__s; 824*700637cbSDimitry Andric __owns_eb_ = false; 825*700637cbSDimitry Andric } else { 826*700637cbSDimitry Andric __extbuf_ = new char[__ebs_]; 827*700637cbSDimitry Andric __owns_eb_ = true; 828*700637cbSDimitry Andric } 829*700637cbSDimitry Andric } else { 830*700637cbSDimitry Andric __extbuf_ = __extbuf_min_; 831*700637cbSDimitry Andric __ebs_ = sizeof(__extbuf_min_); 832*700637cbSDimitry Andric __owns_eb_ = false; 833*700637cbSDimitry Andric } 834*700637cbSDimitry Andric if (!__always_noconv_) { 835*700637cbSDimitry Andric __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 836*700637cbSDimitry Andric if (__s && __ibs_ > sizeof(__extbuf_min_)) { 837*700637cbSDimitry Andric __intbuf_ = __s; 838*700637cbSDimitry Andric __owns_ib_ = false; 839*700637cbSDimitry Andric } else { 840*700637cbSDimitry Andric __intbuf_ = new char_type[__ibs_]; 841*700637cbSDimitry Andric __owns_ib_ = true; 842*700637cbSDimitry Andric } 843*700637cbSDimitry Andric } else { 844*700637cbSDimitry Andric __ibs_ = 0; 845*700637cbSDimitry Andric __intbuf_ = nullptr; 846*700637cbSDimitry Andric __owns_ib_ = false; 847*700637cbSDimitry Andric } 848*700637cbSDimitry Andric return this; 849*700637cbSDimitry Andric} 850*700637cbSDimitry Andric 851*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 852*700637cbSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type 853*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) { 854*700637cbSDimitry Andric if (!__cv_) 855*700637cbSDimitry Andric __throw_bad_cast(); 856*700637cbSDimitry Andric 857*700637cbSDimitry Andric int __width = __cv_->encoding(); 858*700637cbSDimitry Andric if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync()) 859*700637cbSDimitry Andric return pos_type(off_type(-1)); 860*700637cbSDimitry Andric // __width > 0 || __off == 0 861*700637cbSDimitry Andric int __whence; 862*700637cbSDimitry Andric switch (__way) { 863*700637cbSDimitry Andric case ios_base::beg: 864*700637cbSDimitry Andric __whence = SEEK_SET; 865*700637cbSDimitry Andric break; 866*700637cbSDimitry Andric case ios_base::cur: 867*700637cbSDimitry Andric __whence = SEEK_CUR; 868*700637cbSDimitry Andric break; 869*700637cbSDimitry Andric case ios_base::end: 870*700637cbSDimitry Andric __whence = SEEK_END; 871*700637cbSDimitry Andric break; 872*700637cbSDimitry Andric default: 873*700637cbSDimitry Andric return pos_type(off_type(-1)); 874*700637cbSDimitry Andric } 875*700637cbSDimitry Andric# if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) 876*700637cbSDimitry Andric if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence)) 877*700637cbSDimitry Andric return pos_type(off_type(-1)); 878*700637cbSDimitry Andric pos_type __r = ftell(__file_); 879*700637cbSDimitry Andric# else 880*700637cbSDimitry Andric if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence)) 881*700637cbSDimitry Andric return pos_type(off_type(-1)); 882*700637cbSDimitry Andric pos_type __r = ftello(__file_); 883*700637cbSDimitry Andric# endif 884*700637cbSDimitry Andric __r.state(__st_); 885*700637cbSDimitry Andric return __r; 886*700637cbSDimitry Andric} 887*700637cbSDimitry Andric 888*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 889*700637cbSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type 890*700637cbSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) { 891*700637cbSDimitry Andric if (__file_ == nullptr || sync()) 892*700637cbSDimitry Andric return pos_type(off_type(-1)); 893*700637cbSDimitry Andric# if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) 894*700637cbSDimitry Andric if (fseek(__file_, __sp, SEEK_SET)) 895*700637cbSDimitry Andric return pos_type(off_type(-1)); 896*700637cbSDimitry Andric# else 897*700637cbSDimitry Andric if (::fseeko(__file_, __sp, SEEK_SET)) 898*700637cbSDimitry Andric return pos_type(off_type(-1)); 899*700637cbSDimitry Andric# endif 900*700637cbSDimitry Andric __st_ = __sp.state(); 901*700637cbSDimitry Andric return __sp; 902*700637cbSDimitry Andric} 903*700637cbSDimitry Andric 904*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 905*700637cbSDimitry Andricint basic_filebuf<_CharT, _Traits>::sync() { 906*700637cbSDimitry Andric if (__file_ == nullptr) 907*700637cbSDimitry Andric return 0; 908*700637cbSDimitry Andric if (!__cv_) 909*700637cbSDimitry Andric __throw_bad_cast(); 910*700637cbSDimitry Andric 911*700637cbSDimitry Andric if (__cm_ & ios_base::out) { 912*700637cbSDimitry Andric if (this->pptr() != this->pbase()) 913*700637cbSDimitry Andric if (overflow() == traits_type::eof()) 914*700637cbSDimitry Andric return -1; 915*700637cbSDimitry Andric codecvt_base::result __r; 916*700637cbSDimitry Andric do { 917*700637cbSDimitry Andric char* __extbe; 918*700637cbSDimitry Andric __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 919*700637cbSDimitry Andric size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_); 920*700637cbSDimitry Andric if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) 921*700637cbSDimitry Andric return -1; 922*700637cbSDimitry Andric } while (__r == codecvt_base::partial); 923*700637cbSDimitry Andric if (__r == codecvt_base::error) 924*700637cbSDimitry Andric return -1; 925*700637cbSDimitry Andric if (fflush(__file_)) 926*700637cbSDimitry Andric return -1; 927*700637cbSDimitry Andric } else if (__cm_ & ios_base::in) { 928*700637cbSDimitry Andric off_type __c; 929*700637cbSDimitry Andric state_type __state = __st_last_; 930*700637cbSDimitry Andric bool __update_st = false; 931*700637cbSDimitry Andric if (__always_noconv_) 932*700637cbSDimitry Andric __c = this->egptr() - this->gptr(); 933*700637cbSDimitry Andric else { 934*700637cbSDimitry Andric int __width = __cv_->encoding(); 935*700637cbSDimitry Andric __c = __extbufend_ - __extbufnext_; 936*700637cbSDimitry Andric if (__width > 0) 937*700637cbSDimitry Andric __c += __width * (this->egptr() - this->gptr()); 938*700637cbSDimitry Andric else { 939*700637cbSDimitry Andric if (this->gptr() != this->egptr()) { 940*700637cbSDimitry Andric const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback()); 941*700637cbSDimitry Andric __c += __extbufnext_ - __extbuf_ - __off; 942*700637cbSDimitry Andric __update_st = true; 943*700637cbSDimitry Andric } 944*700637cbSDimitry Andric } 945*700637cbSDimitry Andric } 946*700637cbSDimitry Andric# if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) 947*700637cbSDimitry Andric if (fseek(__file_, -__c, SEEK_CUR)) 948*700637cbSDimitry Andric return -1; 949*700637cbSDimitry Andric# else 950*700637cbSDimitry Andric if (::fseeko(__file_, -__c, SEEK_CUR)) 951*700637cbSDimitry Andric return -1; 952*700637cbSDimitry Andric# endif 953*700637cbSDimitry Andric if (__update_st) 954*700637cbSDimitry Andric __st_ = __state; 955*700637cbSDimitry Andric __extbufnext_ = __extbufend_ = __extbuf_; 956*700637cbSDimitry Andric this->setg(nullptr, nullptr, nullptr); 957*700637cbSDimitry Andric __cm_ = 0; 958*700637cbSDimitry Andric } 959*700637cbSDimitry Andric return 0; 960*700637cbSDimitry Andric} 961*700637cbSDimitry Andric 962*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 963*700637cbSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) { 964*700637cbSDimitry Andric sync(); 965*700637cbSDimitry Andric __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(__loc); 966*700637cbSDimitry Andric bool __old_anc = __always_noconv_; 967*700637cbSDimitry Andric __always_noconv_ = __cv_->always_noconv(); 968*700637cbSDimitry Andric if (__old_anc != __always_noconv_) { 969*700637cbSDimitry Andric this->setg(nullptr, nullptr, nullptr); 970*700637cbSDimitry Andric this->setp(nullptr, nullptr); 971*700637cbSDimitry Andric // invariant, char_type is char, else we couldn't get here 972*700637cbSDimitry Andric if (__always_noconv_) // need to dump __intbuf_ 973*700637cbSDimitry Andric { 974*700637cbSDimitry Andric if (__owns_eb_) 975*700637cbSDimitry Andric delete[] __extbuf_; 976*700637cbSDimitry Andric __owns_eb_ = __owns_ib_; 977*700637cbSDimitry Andric __ebs_ = __ibs_; 978*700637cbSDimitry Andric __extbuf_ = (char*)__intbuf_; 979*700637cbSDimitry Andric __ibs_ = 0; 980*700637cbSDimitry Andric __intbuf_ = nullptr; 981*700637cbSDimitry Andric __owns_ib_ = false; 982*700637cbSDimitry Andric } else // need to obtain an __intbuf_. 983*700637cbSDimitry Andric { // If __extbuf_ is user-supplied, use it, else new __intbuf_ 984*700637cbSDimitry Andric if (!__owns_eb_ && __extbuf_ != __extbuf_min_) { 985*700637cbSDimitry Andric __ibs_ = __ebs_; 986*700637cbSDimitry Andric __intbuf_ = (char_type*)__extbuf_; 987*700637cbSDimitry Andric __owns_ib_ = false; 988*700637cbSDimitry Andric __extbuf_ = new char[__ebs_]; 989*700637cbSDimitry Andric __owns_eb_ = true; 990*700637cbSDimitry Andric } else { 991*700637cbSDimitry Andric __ibs_ = __ebs_; 992*700637cbSDimitry Andric __intbuf_ = new char_type[__ibs_]; 993*700637cbSDimitry Andric __owns_ib_ = true; 994*700637cbSDimitry Andric } 995*700637cbSDimitry Andric } 996*700637cbSDimitry Andric } 997*700637cbSDimitry Andric} 998*700637cbSDimitry Andric 999*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1000*700637cbSDimitry Andricbool basic_filebuf<_CharT, _Traits>::__read_mode() { 1001*700637cbSDimitry Andric if (!(__cm_ & ios_base::in)) { 1002*700637cbSDimitry Andric this->setp(nullptr, nullptr); 1003*700637cbSDimitry Andric if (__always_noconv_) 1004*700637cbSDimitry Andric this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_); 1005*700637cbSDimitry Andric else 1006*700637cbSDimitry Andric this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 1007*700637cbSDimitry Andric __cm_ = ios_base::in; 1008*700637cbSDimitry Andric return true; 1009*700637cbSDimitry Andric } 1010*700637cbSDimitry Andric return false; 1011*700637cbSDimitry Andric} 1012*700637cbSDimitry Andric 1013*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1014*700637cbSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::__write_mode() { 1015*700637cbSDimitry Andric if (!(__cm_ & ios_base::out)) { 1016*700637cbSDimitry Andric this->setg(nullptr, nullptr, nullptr); 1017*700637cbSDimitry Andric if (__ebs_ > sizeof(__extbuf_min_)) { 1018*700637cbSDimitry Andric if (__always_noconv_) 1019*700637cbSDimitry Andric this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1)); 1020*700637cbSDimitry Andric else 1021*700637cbSDimitry Andric this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 1022*700637cbSDimitry Andric } else 1023*700637cbSDimitry Andric this->setp(nullptr, nullptr); 1024*700637cbSDimitry Andric __cm_ = ios_base::out; 1025*700637cbSDimitry Andric } 1026*700637cbSDimitry Andric} 1027*700637cbSDimitry Andric 1028*700637cbSDimitry Andric// basic_ifstream 1029*700637cbSDimitry Andric 1030*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1031*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> { 1032*700637cbSDimitry Andricpublic: 1033*700637cbSDimitry Andric typedef _CharT char_type; 1034*700637cbSDimitry Andric typedef _Traits traits_type; 1035*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 1036*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 1037*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 1038*700637cbSDimitry Andric 1039*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ifstream(); 1040*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); 1041*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1042*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); 1043*700637cbSDimitry Andric# endif 1044*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); 1045*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs); 1046*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs); 1047*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs); 1048*700637cbSDimitry Andric 1049*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const; 1050*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_open() const; 1051*700637cbSDimitry Andric void open(const char* __s, ios_base::openmode __mode = ios_base::in); 1052*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1053*700637cbSDimitry Andric void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); 1054*700637cbSDimitry Andric# endif 1055*700637cbSDimitry Andric void open(const string& __s, ios_base::openmode __mode = ios_base::in); 1056*700637cbSDimitry Andric 1057*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode); 1058*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void close(); 1059*700637cbSDimitry Andric 1060*700637cbSDimitry Andricprivate: 1061*700637cbSDimitry Andric basic_filebuf<char_type, traits_type> __sb_; 1062*700637cbSDimitry Andric}; 1063*700637cbSDimitry Andric 1064*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1065*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {} 1066*700637cbSDimitry Andric 1067*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1068*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode) 1069*700637cbSDimitry Andric : basic_istream<char_type, traits_type>(&__sb_) { 1070*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in) == nullptr) 1071*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1072*700637cbSDimitry Andric} 1073*700637cbSDimitry Andric 1074*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1075*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1076*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode) 1077*700637cbSDimitry Andric : basic_istream<char_type, traits_type>(&__sb_) { 1078*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in) == nullptr) 1079*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1080*700637cbSDimitry Andric} 1081*700637cbSDimitry Andric# endif 1082*700637cbSDimitry Andric 1083*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1084*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) 1085*700637cbSDimitry Andric : basic_istream<char_type, traits_type>(&__sb_) { 1086*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in) == nullptr) 1087*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1088*700637cbSDimitry Andric} 1089*700637cbSDimitry Andric 1090*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1091*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) 1092*700637cbSDimitry Andric : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) { 1093*700637cbSDimitry Andric this->set_rdbuf(&__sb_); 1094*700637cbSDimitry Andric} 1095*700637cbSDimitry Andric 1096*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1097*700637cbSDimitry Andricinline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) { 1098*700637cbSDimitry Andric basic_istream<char_type, traits_type>::operator=(std::move(__rhs)); 1099*700637cbSDimitry Andric __sb_ = std::move(__rhs.__sb_); 1100*700637cbSDimitry Andric return *this; 1101*700637cbSDimitry Andric} 1102*700637cbSDimitry Andric 1103*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1104*700637cbSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) { 1105*700637cbSDimitry Andric basic_istream<char_type, traits_type>::swap(__rhs); 1106*700637cbSDimitry Andric __sb_.swap(__rhs.__sb_); 1107*700637cbSDimitry Andric} 1108*700637cbSDimitry Andric 1109*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1110*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) { 1111*700637cbSDimitry Andric __x.swap(__y); 1112*700637cbSDimitry Andric} 1113*700637cbSDimitry Andric 1114*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1115*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const { 1116*700637cbSDimitry Andric return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_); 1117*700637cbSDimitry Andric} 1118*700637cbSDimitry Andric 1119*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1120*700637cbSDimitry Andricinline bool basic_ifstream<_CharT, _Traits>::is_open() const { 1121*700637cbSDimitry Andric return __sb_.is_open(); 1122*700637cbSDimitry Andric} 1123*700637cbSDimitry Andric 1124*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1125*700637cbSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) { 1126*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in)) 1127*700637cbSDimitry Andric this->clear(); 1128*700637cbSDimitry Andric else 1129*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1130*700637cbSDimitry Andric} 1131*700637cbSDimitry Andric 1132*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1133*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1134*700637cbSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) { 1135*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in)) 1136*700637cbSDimitry Andric this->clear(); 1137*700637cbSDimitry Andric else 1138*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1139*700637cbSDimitry Andric} 1140*700637cbSDimitry Andric# endif 1141*700637cbSDimitry Andric 1142*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1143*700637cbSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { 1144*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::in)) 1145*700637cbSDimitry Andric this->clear(); 1146*700637cbSDimitry Andric else 1147*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1148*700637cbSDimitry Andric} 1149*700637cbSDimitry Andric 1150*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1151*700637cbSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) { 1152*700637cbSDimitry Andric if (__sb_.__open(__fd, __mode | ios_base::in)) 1153*700637cbSDimitry Andric this->clear(); 1154*700637cbSDimitry Andric else 1155*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1156*700637cbSDimitry Andric} 1157*700637cbSDimitry Andric 1158*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1159*700637cbSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::close() { 1160*700637cbSDimitry Andric if (__sb_.close() == 0) 1161*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1162*700637cbSDimitry Andric} 1163*700637cbSDimitry Andric 1164*700637cbSDimitry Andric// basic_ofstream 1165*700637cbSDimitry Andric 1166*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1167*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> { 1168*700637cbSDimitry Andricpublic: 1169*700637cbSDimitry Andric typedef _CharT char_type; 1170*700637cbSDimitry Andric typedef _Traits traits_type; 1171*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 1172*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 1173*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 1174*700637cbSDimitry Andric 1175*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ofstream(); 1176*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); 1177*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1178*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); 1179*700637cbSDimitry Andric# endif 1180*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); 1181*700637cbSDimitry Andric 1182*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs); 1183*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs); 1184*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs); 1185*700637cbSDimitry Andric 1186*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const; 1187*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_open() const; 1188*700637cbSDimitry Andric void open(const char* __s, ios_base::openmode __mode = ios_base::out); 1189*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1190*700637cbSDimitry Andric void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); 1191*700637cbSDimitry Andric# endif 1192*700637cbSDimitry Andric void open(const string& __s, ios_base::openmode __mode = ios_base::out); 1193*700637cbSDimitry Andric 1194*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode); 1195*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void close(); 1196*700637cbSDimitry Andric 1197*700637cbSDimitry Andricprivate: 1198*700637cbSDimitry Andric basic_filebuf<char_type, traits_type> __sb_; 1199*700637cbSDimitry Andric}; 1200*700637cbSDimitry Andric 1201*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1202*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {} 1203*700637cbSDimitry Andric 1204*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1205*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode) 1206*700637cbSDimitry Andric : basic_ostream<char_type, traits_type>(&__sb_) { 1207*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out) == nullptr) 1208*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1209*700637cbSDimitry Andric} 1210*700637cbSDimitry Andric 1211*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1212*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1213*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode) 1214*700637cbSDimitry Andric : basic_ostream<char_type, traits_type>(&__sb_) { 1215*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out) == nullptr) 1216*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1217*700637cbSDimitry Andric} 1218*700637cbSDimitry Andric# endif 1219*700637cbSDimitry Andric 1220*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1221*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) 1222*700637cbSDimitry Andric : basic_ostream<char_type, traits_type>(&__sb_) { 1223*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out) == nullptr) 1224*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1225*700637cbSDimitry Andric} 1226*700637cbSDimitry Andric 1227*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1228*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) 1229*700637cbSDimitry Andric : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) { 1230*700637cbSDimitry Andric this->set_rdbuf(&__sb_); 1231*700637cbSDimitry Andric} 1232*700637cbSDimitry Andric 1233*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1234*700637cbSDimitry Andricinline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) { 1235*700637cbSDimitry Andric basic_ostream<char_type, traits_type>::operator=(std::move(__rhs)); 1236*700637cbSDimitry Andric __sb_ = std::move(__rhs.__sb_); 1237*700637cbSDimitry Andric return *this; 1238*700637cbSDimitry Andric} 1239*700637cbSDimitry Andric 1240*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1241*700637cbSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) { 1242*700637cbSDimitry Andric basic_ostream<char_type, traits_type>::swap(__rhs); 1243*700637cbSDimitry Andric __sb_.swap(__rhs.__sb_); 1244*700637cbSDimitry Andric} 1245*700637cbSDimitry Andric 1246*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1247*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) { 1248*700637cbSDimitry Andric __x.swap(__y); 1249*700637cbSDimitry Andric} 1250*700637cbSDimitry Andric 1251*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1252*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const { 1253*700637cbSDimitry Andric return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_); 1254*700637cbSDimitry Andric} 1255*700637cbSDimitry Andric 1256*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1257*700637cbSDimitry Andricinline bool basic_ofstream<_CharT, _Traits>::is_open() const { 1258*700637cbSDimitry Andric return __sb_.is_open(); 1259*700637cbSDimitry Andric} 1260*700637cbSDimitry Andric 1261*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1262*700637cbSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) { 1263*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out)) 1264*700637cbSDimitry Andric this->clear(); 1265*700637cbSDimitry Andric else 1266*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1267*700637cbSDimitry Andric} 1268*700637cbSDimitry Andric 1269*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1270*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1271*700637cbSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) { 1272*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out)) 1273*700637cbSDimitry Andric this->clear(); 1274*700637cbSDimitry Andric else 1275*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1276*700637cbSDimitry Andric} 1277*700637cbSDimitry Andric# endif 1278*700637cbSDimitry Andric 1279*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1280*700637cbSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { 1281*700637cbSDimitry Andric if (__sb_.open(__s, __mode | ios_base::out)) 1282*700637cbSDimitry Andric this->clear(); 1283*700637cbSDimitry Andric else 1284*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1285*700637cbSDimitry Andric} 1286*700637cbSDimitry Andric 1287*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1288*700637cbSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) { 1289*700637cbSDimitry Andric if (__sb_.__open(__fd, __mode | ios_base::out)) 1290*700637cbSDimitry Andric this->clear(); 1291*700637cbSDimitry Andric else 1292*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1293*700637cbSDimitry Andric} 1294*700637cbSDimitry Andric 1295*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1296*700637cbSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::close() { 1297*700637cbSDimitry Andric if (__sb_.close() == nullptr) 1298*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1299*700637cbSDimitry Andric} 1300*700637cbSDimitry Andric 1301*700637cbSDimitry Andric// basic_fstream 1302*700637cbSDimitry Andric 1303*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1304*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> { 1305*700637cbSDimitry Andricpublic: 1306*700637cbSDimitry Andric typedef _CharT char_type; 1307*700637cbSDimitry Andric typedef _Traits traits_type; 1308*700637cbSDimitry Andric typedef typename traits_type::int_type int_type; 1309*700637cbSDimitry Andric typedef typename traits_type::pos_type pos_type; 1310*700637cbSDimitry Andric typedef typename traits_type::off_type off_type; 1311*700637cbSDimitry Andric 1312*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_fstream(); 1313*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s, 1314*700637cbSDimitry Andric ios_base::openmode __mode = ios_base::in | ios_base::out); 1315*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1316*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s, 1317*700637cbSDimitry Andric ios_base::openmode __mode = ios_base::in | ios_base::out); 1318*700637cbSDimitry Andric# endif 1319*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s, 1320*700637cbSDimitry Andric ios_base::openmode __mode = ios_base::in | ios_base::out); 1321*700637cbSDimitry Andric 1322*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs); 1323*700637cbSDimitry Andric 1324*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs); 1325*700637cbSDimitry Andric 1326*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs); 1327*700637cbSDimitry Andric 1328*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const; 1329*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool is_open() const; 1330*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); 1331*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1332*700637cbSDimitry Andric void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); 1333*700637cbSDimitry Andric# endif 1334*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); 1335*700637cbSDimitry Andric 1336*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void close(); 1337*700637cbSDimitry Andric 1338*700637cbSDimitry Andricprivate: 1339*700637cbSDimitry Andric basic_filebuf<char_type, traits_type> __sb_; 1340*700637cbSDimitry Andric}; 1341*700637cbSDimitry Andric 1342*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1343*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {} 1344*700637cbSDimitry Andric 1345*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1346*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode) 1347*700637cbSDimitry Andric : basic_iostream<char_type, traits_type>(&__sb_) { 1348*700637cbSDimitry Andric if (__sb_.open(__s, __mode) == nullptr) 1349*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1350*700637cbSDimitry Andric} 1351*700637cbSDimitry Andric 1352*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1353*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1354*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode) 1355*700637cbSDimitry Andric : basic_iostream<char_type, traits_type>(&__sb_) { 1356*700637cbSDimitry Andric if (__sb_.open(__s, __mode) == nullptr) 1357*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1358*700637cbSDimitry Andric} 1359*700637cbSDimitry Andric# endif 1360*700637cbSDimitry Andric 1361*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1362*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) 1363*700637cbSDimitry Andric : basic_iostream<char_type, traits_type>(&__sb_) { 1364*700637cbSDimitry Andric if (__sb_.open(__s, __mode) == nullptr) 1365*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1366*700637cbSDimitry Andric} 1367*700637cbSDimitry Andric 1368*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1369*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) 1370*700637cbSDimitry Andric : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) { 1371*700637cbSDimitry Andric this->set_rdbuf(&__sb_); 1372*700637cbSDimitry Andric} 1373*700637cbSDimitry Andric 1374*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1375*700637cbSDimitry Andricinline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) { 1376*700637cbSDimitry Andric basic_iostream<char_type, traits_type>::operator=(std::move(__rhs)); 1377*700637cbSDimitry Andric __sb_ = std::move(__rhs.__sb_); 1378*700637cbSDimitry Andric return *this; 1379*700637cbSDimitry Andric} 1380*700637cbSDimitry Andric 1381*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1382*700637cbSDimitry Andricinline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) { 1383*700637cbSDimitry Andric basic_iostream<char_type, traits_type>::swap(__rhs); 1384*700637cbSDimitry Andric __sb_.swap(__rhs.__sb_); 1385*700637cbSDimitry Andric} 1386*700637cbSDimitry Andric 1387*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1388*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) { 1389*700637cbSDimitry Andric __x.swap(__y); 1390*700637cbSDimitry Andric} 1391*700637cbSDimitry Andric 1392*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1393*700637cbSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const { 1394*700637cbSDimitry Andric return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_); 1395*700637cbSDimitry Andric} 1396*700637cbSDimitry Andric 1397*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1398*700637cbSDimitry Andricinline bool basic_fstream<_CharT, _Traits>::is_open() const { 1399*700637cbSDimitry Andric return __sb_.is_open(); 1400*700637cbSDimitry Andric} 1401*700637cbSDimitry Andric 1402*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1403*700637cbSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) { 1404*700637cbSDimitry Andric if (__sb_.open(__s, __mode)) 1405*700637cbSDimitry Andric this->clear(); 1406*700637cbSDimitry Andric else 1407*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1408*700637cbSDimitry Andric} 1409*700637cbSDimitry Andric 1410*700637cbSDimitry Andric# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR 1411*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1412*700637cbSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) { 1413*700637cbSDimitry Andric if (__sb_.open(__s, __mode)) 1414*700637cbSDimitry Andric this->clear(); 1415*700637cbSDimitry Andric else 1416*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1417*700637cbSDimitry Andric} 1418*700637cbSDimitry Andric# endif 1419*700637cbSDimitry Andric 1420*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1421*700637cbSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { 1422*700637cbSDimitry Andric if (__sb_.open(__s, __mode)) 1423*700637cbSDimitry Andric this->clear(); 1424*700637cbSDimitry Andric else 1425*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1426*700637cbSDimitry Andric} 1427*700637cbSDimitry Andric 1428*700637cbSDimitry Andrictemplate <class _CharT, class _Traits> 1429*700637cbSDimitry Andricinline void basic_fstream<_CharT, _Traits>::close() { 1430*700637cbSDimitry Andric if (__sb_.close() == nullptr) 1431*700637cbSDimitry Andric this->setstate(ios_base::failbit); 1432*700637cbSDimitry Andric} 1433*700637cbSDimitry Andric 1434*700637cbSDimitry Andric# if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 1435*700637cbSDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>; 1436*700637cbSDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>; 1437*700637cbSDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>; 1438*700637cbSDimitry Andric# endif 1439*700637cbSDimitry Andric 1440*700637cbSDimitry Andric_LIBCPP_END_NAMESPACE_STD 1441*700637cbSDimitry Andric 1442*700637cbSDimitry Andric#endif // _LIBCPP_HAS_NO_FILESYSTEM 1443*700637cbSDimitry Andric 1444*700637cbSDimitry Andric_LIBCPP_POP_MACROS 1445*700637cbSDimitry Andric 1446*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 1447*700637cbSDimitry Andric# include <__cxx03/atomic> 1448*700637cbSDimitry Andric# include <__cxx03/cstdlib> 1449*700637cbSDimitry Andric# include <__cxx03/iosfwd> 1450*700637cbSDimitry Andric# include <__cxx03/limits> 1451*700637cbSDimitry Andric# include <__cxx03/mutex> 1452*700637cbSDimitry Andric# include <__cxx03/new> 1453*700637cbSDimitry Andric# include <__cxx03/stdexcept> 1454*700637cbSDimitry Andric# include <__cxx03/type_traits> 1455*700637cbSDimitry Andric#endif 1456*700637cbSDimitry Andric 1457*700637cbSDimitry Andric#endif // _LIBCPP___CXX03_FSTREAM 1458