cheatah
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 cheatah
9// executable only when the program `import io`s.
10namespace cheatah::io {
12std::string str(const std::string& value) { return value; }
13std::string str(bool b) { return b ? "True" : "False"; }
14std::string str(signed char v) { return std::to_string(static_cast<int>(v)); }
15std::string str(unsigned char v) { return std::to_string(static_cast<unsigned>(v)); }
17std::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;
25std::string repr(const std::string& value) { return "'" + value + "'"; }
26std::string repr(const char* value) { return "'" + std::string(value) + "'"; }
28namespace detail {
29void format_into(std::ostringstream& os, std::string_view fmt) {
30 os << fmt; // no args left — emit the remainder verbatim
32} // namespace detail
34std::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;
43File::File(const std::string& path, std::string_view mode) { open(path, mode); }
44File::~File() { close(); }
46void File::open(const std::string& path, std::string_view mode) {
47 stream_.open(path, translate_mode(mode));
49bool File::is_open() const { return stream_.is_open(); }
50void File::close() {
51 if (stream_.is_open()) {
52 stream_.close();
53 }
56std::string File::read() {
57 std::ostringstream ss;
58 ss << stream_.rdbuf();
59 return ss.str();
61std::string File::readline() {
62 std::string line;
63 std::getline(stream_, line);
64 return line;
66std::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;
75std::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;
87File open(const std::string& path, std::string_view mode) { return File(path, mode); }
89std::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();
97} // namespace cheatah::io