#ifndef CRITERION_INTERNAL_STREAM_HXX_ # define CRITERION_INTERNAL_STREAM_HXX_ # include # include # include # include "stdio_filebuf.hxx" namespace criterion { namespace internal { template class stream_mixin : public Super { public: stream_mixin(FILE* f) : Super() , fbuf(new stdio_sync_filebuf(f)) , file(f) { std::ios::rdbuf(&*fbuf); } # if __cplusplus > 199711L stream_mixin(const stream_mixin& other) = delete; stream_mixin& operator=(const stream_mixin& other) = delete; # endif stream_mixin(stream_mixin&& other) : fbuf(std::move(other.fbuf)), file(std::move(other.file)) {} stream_mixin& operator=(stream_mixin&& other) { fbuf = std::move(other.fbuf); file = std::move(other.file); } void close(void) { Super::flush(); Super::close(); std::fclose(file); } private: std::shared_ptr> fbuf; std::FILE* file; }; template class basic_ofstream : public stream_mixin> { typedef stream_mixin> super; public: basic_ofstream(FILE* f) : super(f) {} basic_ofstream(basic_ofstream&& other) : super(std::move(other)) {} }; template class basic_ifstream : public stream_mixin> { typedef stream_mixin> super; public: basic_ifstream(FILE* f) : super(f) {} basic_ifstream(basic_ifstream&& other) : super(std::move(other)) {} }; template class basic_fstream : public stream_mixin> { typedef stream_mixin> super; public: basic_fstream(FILE* f) : super(f) {} basic_fstream(basic_fstream&& other) : super(std::move(other)) {} }; struct get_redirected_out_stream_ { static inline basic_ofstream& call(std::FILE* f) { static std::unique_ptr> stream; if (!stream) stream.reset(new basic_ofstream(f)); return *stream; } }; struct get_redirected_in_stream_ { static inline basic_ifstream& call(std::FILE* f) { static std::unique_ptr> stream; if (!stream) stream.reset(new basic_ifstream(f)); return *stream; } }; }} #endif /* !CRITERION_INTERNAL_STREAM_HXX_ */