Skip to content

Instantly share code, notes, and snippets.

@syldrathecat
Created June 29, 2017 14:54
Show Gist options
  • Save syldrathecat/644d49351d025ce042e5b87ffb106b8a to your computer and use it in GitHub Desktop.
Save syldrathecat/644d49351d025ce042e5b87ffb106b8a to your computer and use it in GitHub Desktop.
#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