6 #define WIN32_LEAN_AND_MEAN
16 // Windows' std::ifstream fails with non-ANSI paths since the standard only
17 // specifies names using const char* (or std::string). MSVC has a non-standard
18 // extension using const wchar_t* (or std::wstring?) to handle Unicode paths,
19 // but not all Windows compilers support it. So we have to make our own istream
20 // that accepts UTF-8 paths and forwards to Unicode-aware I/O functions.
21 class filebuf final
: public std::streambuf
{
22 std::array
<char_type
,4096> mBuffer
;
23 HANDLE mFile
{INVALID_HANDLE_VALUE
};
25 int_type
underflow() override
;
26 pos_type
seekoff(off_type offset
, std::ios_base::seekdir whence
, std::ios_base::openmode mode
) override
;
27 pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
) override
;
33 bool open(const wchar_t *filename
, std::ios_base::openmode mode
);
34 bool open(const char *filename
, std::ios_base::openmode mode
);
36 bool is_open() const noexcept
{ return mFile
!= INVALID_HANDLE_VALUE
; }
39 // Inherit from std::istream to use our custom streambuf
40 class ifstream final
: public std::istream
{
44 ifstream(const wchar_t *filename
, std::ios_base::openmode mode
= std::ios_base::in
);
45 ifstream(const std::wstring
&filename
, std::ios_base::openmode mode
= std::ios_base::in
)
46 : ifstream(filename
.c_str(), mode
) { }
47 ifstream(const char *filename
, std::ios_base::openmode mode
= std::ios_base::in
);
48 ifstream(const std::string
&filename
, std::ios_base::openmode mode
= std::ios_base::in
)
49 : ifstream(filename
.c_str(), mode
) { }
52 bool is_open() const noexcept
{ return mStreamBuf
.is_open(); }
63 using filebuf
= std::filebuf
;
64 using ifstream
= std::ifstream
;
70 #endif /* AL_FSTREAM_H */