Last active
September 20, 2015 20:35
-
-
Save Snaipe/cc51a98fbc1ffb7af358 to your computer and use it in GitHub Desktop.
Inherited basic_fstream operator weirdness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <cstdio> | |
#include <fstream> | |
#include <iostream> | |
#include <memory> | |
#include <string> | |
template <typename CharT> | |
class my_basic_fstream : public std::basic_fstream<CharT> { | |
public: | |
my_basic_fstream(std::FILE *f) : std::basic_fstream<char>(f) {} | |
}; | |
using my_fstream = my_basic_fstream<char>; | |
template <typename CharT> | |
struct get_file_stream_ { | |
static inline my_basic_fstream<CharT>& call(std::FILE* f) { | |
static std::unique_ptr<my_basic_fstream<CharT>> stream; | |
if (!stream) | |
stream.reset(new my_basic_fstream<CharT>(f)); | |
return *stream; | |
} | |
}; | |
static inline my_fstream& get_tmp_stream() { | |
return get_file_stream_<char>::call(std::tmpfile()); | |
} | |
int main(void) { | |
my_fstream& f = get_tmp_stream(); | |
f << "Foo"; | |
f.seekg(0); | |
std::string written; | |
f >> written; | |
f.close(); | |
if (written == "Foo") | |
std::cout << "All is well." << std::endl; | |
else | |
std::cout << "Expected \"Foo\", got \"" << written << "\"." << std::endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <cstdio> | |
#include <fstream> | |
#include <iostream> | |
#include <memory> | |
#include <string> | |
#ifdef __GNUC__ | |
# if defined(__MINGW32__) || defined(__MINGW64__) | |
# define off_t _off_t | |
# define off64_t _off64_t | |
# endif | |
# include <ext/stdio_sync_filebuf.h> | |
# if defined(__MINGW32__) || defined(__MINGW64__) | |
# undef off_t | |
# undef off64_t | |
# endif | |
#endif | |
template <typename CharT> | |
class my_basic_fstream : public std::basic_fstream<CharT> { | |
public: | |
my_basic_fstream(std::FILE* f) | |
#ifdef __GNUC__ | |
: std::basic_fstream<CharT>() | |
, fbuf(new ::__gnu_cxx::stdio_sync_filebuf<CharT>(f)) | |
#else | |
: std::basic_fstream<CharT>(f) | |
#endif | |
, file(f) | |
{ | |
#ifdef __GNUC__ | |
std::ios::rdbuf(&*fbuf); | |
#endif | |
} | |
my_basic_fstream(const my_basic_fstream& other) = delete; | |
my_basic_fstream& operator=(const my_basic_fstream& other) = delete; | |
my_basic_fstream(my_basic_fstream&& other) : | |
#ifdef __GNUC__ | |
fbuf(std::move(other.fbuf)), | |
#endif | |
file(std::move(other.file)) | |
{} | |
my_basic_fstream& operator=(my_basic_fstream&& other) { | |
#ifdef __GNUC__ | |
fbuf = std::move(other.fbuf); | |
#endif | |
file = std::move(other.file); | |
} | |
void close(void) { | |
std::basic_fstream<CharT>::flush(); | |
std::basic_fstream<CharT>::close(); | |
std::fclose(file); | |
} | |
private: | |
#ifdef __GNUC__ | |
std::shared_ptr<::__gnu_cxx::stdio_sync_filebuf<CharT>> fbuf; | |
#endif | |
std::FILE* file; | |
}; | |
using my_fstream = my_basic_fstream<char>; | |
template <typename CharT> | |
struct get_file_stream_ { | |
static inline my_basic_fstream<CharT>& call(std::FILE* f) { | |
static std::unique_ptr<my_basic_fstream<CharT>> stream; | |
if (!stream) | |
stream.reset(new my_basic_fstream<CharT>(f)); | |
return *stream; | |
} | |
}; | |
static inline my_fstream& get_tmp_stream() { | |
return get_file_stream_<char>::call(std::tmpfile()); | |
} | |
int main(void) { | |
my_fstream& f = get_tmp_stream(); | |
f << "Foo"; | |
f.seekg(0); | |
std::string written; | |
f >> written; | |
f.close(); | |
if (written == "Foo") | |
std::cout << "All is well." << std::endl; | |
else | |
std::cout << "Expected \"Foo\", got \"" << written << "\"." << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment