Created
June 29, 2017 14:54
-
-
Save syldrathecat/644d49351d025ce042e5b87ffb106b8a to your computer and use it in GitHub Desktop.
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
#ifndef CIO_CIO_HPP | |
#define CIO_CIO_HPP | |
#include <cstdio> | |
#include <functional> | |
#include <limits> | |
#include <string> | |
#include <type_traits> | |
#include <utility> | |
namespace cio | |
{ | |
class stream | |
{ | |
private: | |
FILE* fh; | |
public: | |
typedef FILE* element_type; | |
stream(FILE* fh) | |
: fh(fh) | |
{ } | |
stream(const char* filename, int flags) | |
: fh(nullptr) | |
{ | |
open(filename, flags); | |
} | |
stream(const char* filename, const char* modestr) | |
: fh(nullptr) | |
{ | |
open(filename, modestr); | |
} | |
stream(stream&& other) | |
{ | |
fh = other.fh; | |
other.fh = nullptr; | |
} | |
stream(const stream&) = delete; | |
stream& operator=(const stream&) = delete; | |
bool open(const char* filename, const char* modestr) | |
{ | |
if (fh) | |
fclose(fh); | |
fh = fopen(filename, modestr); | |
return (fh != nullptr); | |
} | |
void close() | |
{ | |
fclose(fh); | |
fh = nullptr; | |
} | |
FILE* get() const | |
{ | |
return fh; | |
} | |
FILE* release() | |
{ | |
FILE* temp_fh = fh; | |
fh = nullptr; | |
return temp_fh; | |
} | |
void reset(FILE* new_fh = nullptr) | |
{ | |
fh = new_fh; | |
} | |
void swap(stream& other) | |
{ | |
std::swap(fh, other.fh); | |
} | |
bool is_open() const | |
{ | |
return fh != nullptr; | |
} | |
bool eof() const | |
{ | |
return std::feof(fh); | |
} | |
bool error() const | |
{ | |
return std::ferror(fh); | |
} | |
void clear() | |
{ | |
std::clearerr(fh); | |
} | |
explicit operator bool() const | |
{ | |
return !error(); | |
} | |
bool put(char c) | |
{ | |
int result = std::fputc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool put(signed char c) | |
{ | |
int result = std::fputc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool put(unsigned char c) | |
{ | |
int result = std::fputc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool get(char& c) | |
{ | |
int result = std::fgetc(fh); | |
bool ok = (result != EOF); | |
if (ok) | |
c = static_cast<char>(result); | |
return ok; | |
} | |
bool get(signed char& c) | |
{ | |
int result = std::fgetc(fh); | |
bool ok = (result != EOF); | |
if (ok) | |
c = static_cast<signed char>(result); | |
return ok; | |
} | |
bool get(unsigned char& c) | |
{ | |
int result = std::fgetc(fh); | |
bool ok = (result != EOF); | |
if (ok) | |
c = static_cast<unsigned char>(result); | |
return ok; | |
} | |
bool unget(char c) | |
{ | |
int result = std::ungetc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool unget(signed char c) | |
{ | |
int result = std::ungetc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool unget(unsigned char c) | |
{ | |
int result = std::ungetc(static_cast<int>(c), fh); | |
return (result != EOF); | |
} | |
bool write(const char* data) | |
{ | |
int result = std::fputs(data, fh); | |
return (result > 0); | |
} | |
std::size_t write(const char* data, std::size_t n) | |
{ | |
return std::fwrite(data, 1, n, fh); | |
} | |
std::size_t read(char* data, std::size_t n) | |
{ | |
return std::fread(data, 1, n, fh); | |
} | |
void rewind() | |
{ | |
std::rewind(fh); | |
} | |
bool seek(long offset) | |
{ | |
int result = std::fseek(fh, offset, SEEK_SET); | |
return (result == 0); | |
} | |
bool skip(long offset) | |
{ | |
int result = std::fseek(fh, offset, SEEK_CUR); | |
return (result == 0); | |
} | |
bool seek_reverse(long offset) | |
{ | |
int result = std::fseek(fh, offset, SEEK_END); | |
return (result == 0); | |
} | |
long tell() | |
{ | |
return std::ftell(fh); | |
} | |
void flush() | |
{ | |
std::fflush(fh); | |
} | |
~stream() | |
{ | |
if (fh) | |
close(); | |
} | |
}; | |
struct io_flush_term_t { }; | |
struct io_endl_term_t { }; | |
constexpr io_flush_term_t flush; | |
constexpr io_endl_term_t endl; | |
inline stream& operator <<(stream& io, bool b) | |
{ | |
io.write(b ? "true" : "false"); | |
return io; | |
} | |
inline stream& operator <<(stream& io, void* p) | |
{ | |
fprintf(io.get(), "%p", p); | |
return io; | |
} | |
inline stream& operator <<(stream& io, char c) | |
{ | |
io.put(c); | |
return io; | |
} | |
inline stream& operator <<(stream& io, signed char c) | |
{ | |
io.put(c); | |
return io; | |
} | |
inline stream& operator <<(stream& io, unsigned char c) | |
{ | |
io.put(c); | |
return io; | |
} | |
stream& operator <<(stream& io, int i); | |
stream& operator <<(stream& io, unsigned int i); | |
inline stream& operator <<(stream& io, short i) | |
{ | |
return (io << static_cast<int>(i)); | |
} | |
inline stream& operator <<(stream& io, unsigned short i) | |
{ | |
return (io << static_cast<unsigned int>(i)); | |
} | |
inline stream& operator <<(stream& io, int i) | |
{ | |
std::fprintf(io.get(), "%i", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, unsigned int i) | |
{ | |
std::fprintf(io.get(), "%u", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, long i) | |
{ | |
std::fprintf(io.get(), "%li", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, unsigned long i) | |
{ | |
std::fprintf(io.get(), "%lu", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, long long i) | |
{ | |
std::fprintf(io.get(), "%lli", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, unsigned long long i) | |
{ | |
std::fprintf(io.get(), "%llu", i); | |
return io; | |
} | |
inline stream& operator <<(stream& io, float f) | |
{ | |
std::fprintf(io.get(), "%f", f); | |
return io; | |
} | |
inline stream& operator <<(stream& io, double f) | |
{ | |
std::fprintf(io.get(), "%f", f); | |
return io; | |
} | |
inline stream& operator <<(stream& io, long double f) | |
{ | |
std::fprintf(io.get(), "%Lf", f); | |
return io; | |
} | |
inline stream& operator <<(stream& io, const char* s) | |
{ | |
io.write(s); | |
return io; | |
} | |
template <std::size_t Sz> stream& operator <<(stream& io, const char s[Sz]) | |
{ | |
io.write(s, Sz); | |
return io; | |
} | |
inline stream& operator <<(stream& io, const std::string& s) | |
{ | |
io.write(s.data(), s.size()); | |
return io; | |
} | |
inline stream& operator <<(stream& io, const io_flush_term_t&) | |
{ | |
io.flush(); | |
return io; | |
} | |
inline stream& operator <<(stream& io, const io_endl_term_t&) | |
{ | |
io.put('\n'); | |
io.flush(); | |
return io; | |
} | |
// inline stream& operator <<(stream& io, const std::string_view& sv); | |
inline void swap(stream& a, stream& b) | |
{ | |
a.swap(b); | |
} | |
extern stream in; | |
extern stream out; | |
extern stream err; | |
} | |
namespace std | |
{ | |
template <> struct hash<::cio::stream> | |
{ | |
typedef ::cio::stream argument_type; | |
typedef ::std::size_t result_type; | |
::std::size_t operator()(const ::cio::stream& io) const | |
{ | |
return ::std::hash<FILE*>()(io.get()); | |
} | |
}; | |
template <> struct hash<::cio::stream::mode_t> | |
: public hash<std::underlying_type<::cio::stream::mode_t>::type> | |
{ }; | |
} | |
#endif // CIO_CIO_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment