Source
stdlib/io/io.cpp
1
// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).2
// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.3
#include "io.hpp"5
#include <algorithm>6
#include <cstdio>8
// Compiled (non-template) symbols of the io module. Linked into a cheatah9
// executable only when the program `import io`s.10
namespace cheatah::io {12
std::string str(const std::string& value) { return value; }13
std::string str(bool b) { return b ? "True" : "False"; }14
std::string str(signed char v) { return std::to_string(static_cast<int>(v)); }15
std::string str(unsigned char v) { return std::to_string(static_cast<unsigned>(v)); }17
std::string fixed(double value, long long places) {18
const int p = static_cast<int>(std::clamp<long long>(places, 0, 17));19
const int n = std::snprintf(nullptr, 0, "%.*f", p, value);20
std::string out(static_cast<std::size_t>(n), '\0');21
std::snprintf(out.data(), out.size() + 1, "%.*f", p, value);22
return out;23
}25
std::string repr(const std::string& value) { return "'" + value + "'"; }26
std::string repr(const char* value) { return "'" + std::string(value) + "'"; }28
namespace detail {29
void format_into(std::ostringstream& os, std::string_view fmt) {30
os << fmt; // no args left — emit the remainder verbatim31
}32
} // namespace detail34
std::string input(std::string_view prompt) {35
if (!prompt.empty()) {36
std::cout << prompt << std::flush;37
}38
std::string line;39
std::getline(std::cin, line);40
return line;41
}43
File::File(const std::string& path, std::string_view mode) { open(path, mode); }44
File::~File() { close(); }46
void File::open(const std::string& path, std::string_view mode) {47
stream_.open(path, translate_mode(mode));48
}49
bool File::is_open() const { return stream_.is_open(); }50
void File::close() {51
if (stream_.is_open()) {52
stream_.close();53
}54
}56
std::string File::read() {57
std::ostringstream ss;58
ss << stream_.rdbuf();59
return ss.str();60
}61
std::string File::readline() {62
std::string line;63
std::getline(stream_, line);64
return line;65
}66
std::vector<std::string> File::readlines() {67
std::vector<std::string> out;68
std::string line;69
while (std::getline(stream_, line)) {70
out.push_back(line);71
}72
return out;73
}75
std::ios::openmode File::translate_mode(std::string_view mode) {76
// Python modes: r / w / a (+ optional '+' for read-update, 'b' for binary).77
std::ios::openmode m{};78
const bool plus = mode.find('+') != std::string_view::npos;79
if (mode.find('b') != std::string_view::npos) m |= std::ios::binary;80
if (mode.find('r') != std::string_view::npos) { m |= std::ios::in; if (plus) m |= std::ios::out; }81
if (mode.find('w') != std::string_view::npos) { m |= std::ios::out | std::ios::trunc; if (plus) m |= std::ios::in; }82
if (mode.find('a') != std::string_view::npos) { m |= std::ios::out | std::ios::app; if (plus) m |= std::ios::in; }83
if (m == std::ios::openmode{}) m = std::ios::in; // default 'r'84
return m;85
}87
File open(const std::string& path, std::string_view mode) { return File(path, mode); }89
std::string read_file(const std::string& path) {90
std::ifstream in(path, std::ios::binary);91
if (!in) return std::string();92
std::ostringstream ss;93
ss << in.rdbuf();94
return ss.str();95
}97
} // namespace cheatah::io