Elvelt

Standard Library

C++ implementation reference (`mpl::System::*`)

C++ implementation reference (mpl::System::*)

The C++ implementation of the MPL Standard Library is defined in MPL_Standard/CppImpl.h (335 lines). It declares every stdlib function in the mpl::System namespace, with sub-namespaces for each module. All functions are inline and header-only (C++20).

This document is a reference — the source-of-truth function signatures and behavior. For end-to-end usage and source-language mapping, see modules.md.

File structure

// MPL_Standard/CppImpl.h:26
namespace mpl { namespace System {

namespace Console    { /* … */ }   // line 32
namespace Environment { /* … */ }   // line 65
namespace IO         { /* … */     // line 116
    namespace Path   { /* … */ }   // line 159
} // IO
namespace Process    { /* … */ }   // line 192
namespace Math       { /* … */ }   // line 212
namespace String     { /* … */ }   // line 259
namespace DateTime   { /* … */ }   // line 320

}}

Includes

CppImpl.h brings in only what is strictly needed for the canonical implementations (lines 14-24):

#include <string>
#include <vector>
#include <optional>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <cmath>
#include <chrono>
#include <cctype>

Notably absent: <regex> (no stdlib regex), <thread>, <atomic>, Boost, OpenSSL. These are brought in by empl_core.h for the runtime, but CppImpl.h is deliberately minimal.

Console module (mpl::System::Console)

Source: CppImpl.h:32-60

inline void WriteLine(const std::string& text) {
    std::cout << text << std::endl;
}

inline void WriteLine() {
    std::cout << std::endl;
}

inline void Write(const std::string& text) {
    std::cout << text;
}

inline void ErrorWriteLine(const std::string& text) {
    std::cerr << text << std::endl;
}

inline void ErrorWrite(const std::string& text) {
    std::cerr << text;
}

inline std::string ReadLine() {
    std::string line;
    std::getline(std::cin, line);
    return line;
}
Function Line Behavior notes
WriteLine(text) 34 Uses std::endl for newline (flushes std::cout). For large output, prefer "\n" for performance.
WriteLine() 38 Emits just a newline.
Write(text) 42 No flush — subsequent writes may not appear immediately.
ErrorWriteLine(text) 46 Uses std::cerr (unbuffered by default).
ErrorWrite(text) 50 No newline, no implicit flush.
ReadLine() 54 Uses std::getline (delimiter-aware). Returns empty on EOF.

Environment module (mpl::System::Environment)

Source: CppImpl.h:65-111

inline std::optional<std::string> GetVariable(const std::string& name) {
    const char* value = std::getenv(name.c_str());
    if (value) {
        return std::string(value);
    }
    return std::nullopt;
}

inline void SetVariable(const std::string& name, const std::string& value) {
#if defined(_WIN32)
    _putenv_s(name.c_str(), value.c_str());
#else
    setenv(name.c_str(), value.c_str(), 1);
#endif
}

inline std::string GetCurrentDirectory() {
    return std::filesystem::current_path().string();
}

inline void SetCurrentDirectory(const std::string& path) {
    std::filesystem::current_path(path);
}

inline std::string GetPlatform() {
#if defined(_WIN32)
    return "win32";
#elif defined(__APPLE__)
    return "darwin";
#elif defined(__linux__)
    return "linux";
#else
    return "unknown";
#endif
}

inline std::string GetNewLine() {
#if defined(_WIN32)
    return "\r\n";
#else
    return "\n";
#endif
}
Function Line Notes
GetVariable(name) 67 Returns std::nullopt for unset variables. Frontend mapper should treat this as undefined / null in the source language.
SetVariable(name, value) 75 Windows uses _putenv_s; POSIX uses setenv(..., 1) to overwrite.
GetCurrentDirectory() 83 Returns the absolute CWD.
SetCurrentDirectory(path) 87 Throws std::filesystem::filesystem_error on failure.
GetPlatform() 91 Returns canonical platform name.
GetNewLine() 103 "\r\n" on Windows, "\n" elsewhere.

IO module (mpl::System::IO)

Source: CppImpl.h:116-187

inline std::string ReadFileText(const std::string& path) {
    std::ifstream file(path, std::ios::binary);
    if (!file) {
        throw std::runtime_error("Failed to read file: " + path);
    }
    return std::string((std::istreambuf_iterator<char>(file)),
                       std::istreambuf_iterator<char>());
}

inline void WriteFileText(const std::string& path, const std::string& content) {
    std::ofstream file(path, std::ios::binary);
    if (!file) {
        throw std::runtime_error("Failed to write file: " + path);
    }
    file << content;
}

inline bool FileExists(const std::string& path) {
    return std::filesystem::exists(path);
}

inline void DeleteFile(const std::string& path) {
    std::filesystem::remove(path);
}

inline void CreateDirectory(const std::string& path) {
    std::filesystem::create_directories(path);
}

inline void DeleteDirectory(const std::string& path) {
    std::filesystem::remove_all(path);
}

inline std::vector<std::string> GetDirectoryEntries(const std::string& path) {
    std::vector<std::string> result;
    for (const auto& entry : std::filesystem::directory_iterator(path)) {
        result.push_back(entry.path().string());
    }
    return result;
}
Function Line Notes
ReadFileText(path) 118 Opens in binary mode (no Windows CRLF translation). Throws on open failure.
WriteFileText(path, content) 127 Binary mode; overwrites if exists.
FileExists(path) 135 true for both files and directories.
DeleteFile(path) 139 std::filesystem::remove returns false silently if not present.
CreateDirectory(path) 143 create_directories is recursive and idempotent.
DeleteDirectory(path) 147 remove_all is recursive.
GetDirectoryEntries(path) 151 Returns absolute paths. Order is OS-dependent.

Path sub-module (mpl::System::IO::Path)

Source: CppImpl.h:159-185

inline std::string Join(const std::vector<std::string>& parts) {
    std::filesystem::path p;
    for (const auto& part : parts) {
        p /= part;
    }
    return p.string();
}

inline std::string GetDirectoryName(const std::string& path) {
    return std::filesystem::path(path).parent_path().string();
}

inline std::string GetFileName(const std::string& path) {
    return std::filesystem::path(path).filename().string();
}

inline std::string GetExtension(const std::string& path) {
    return std::filesystem::path(path).extension().string();
}

inline std::string GetFullPath(const std::string& path) {
    return std::filesystem::absolute(path).string();
}
Function Line Notes
Join(parts) 161 Uses path::operator/= (handles separator correctly).
GetDirectoryName(path) 169 Returns empty for root / no-parent paths.
GetFileName(path) 173 Just the filename (no directory).
GetExtension(path) 177 Returns "" if no extension (does NOT include the dot if absent).
GetFullPath(path) 181 std::filesystem::absolute resolves against CWD if relative.

Process module (mpl::System::Process)

Source: CppImpl.h:192-207

inline void Exit(int code) {
    std::exit(code);
}

inline std::vector<std::string> GetCommandLineArgs() {
    // Placeholder: actual implementation requires integration with main() arguments
    return {};
}

inline std::string GetRuntimeVersion() {
    return "MPL_Runtime_1.0";
}
Function Line Notes
Exit(code) 194 Wraps std::exit. Does NOT run C++ destructors of objects in other translation units.
GetCommandLineArgs() 198 Placeholder — returns empty vector. Real implementation requires hooking into main(int argc, char** argv) and storing the args in a static accessor.
GetRuntimeVersion() 203 Returns the constant "MPL_Runtime_1.0".

Note. GetCommandLineArgs() is the only stdlib function in CppImpl.h that is a placeholder. The C++ backend wires up the real implementation by injecting the args into a global accessor at program start. See MPL_Compiler.cpp and the generated _mpl_runtime_init(argc, argv) call.

Math module (mpl::System::Math)

Source: CppImpl.h:212-254

inline double Abs(double value)    { return std::abs(value); }
inline double Floor(double value)  { return std::floor(value); }
inline double Ceil(double value)   { return std::ceil(value); }
inline double Round(double value)  { return std::round(value); }
inline double Sqrt(double value)   { return std::sqrt(value); }
inline double Pow(double base, double exponent) { return std::pow(base, exponent); }
inline double Max(double a, double b) { return (a > b) ? a : b; }
inline double Min(double a, double b) { return (a < b) ? a : b; }
inline double Pi() { return 3.14159265358979323846; }
inline double E()  { return 2.71828182845904523536; }
Function Line Notes
Abs(value) 214 Wraps std::abs (which is overloaded for integers).
Floor(value) 218 std::floor — round toward -∞.
Ceil(value) 222 std::ceil — round toward +∞.
Round(value) 226 std::round — half away from zero.
Sqrt(value) 230 Returns NaN for negative input.
Pow(base, exp) 234 Edge cases: pow(0, 0) = 1, pow(0, -1) = +Inf, etc.
Max(a, b) 238 Manual (a > b) ? a : b (avoids <algorithm> std::max macro surprises).
Min(a, b) 242 Manual (a < b) ? a : b.
Pi() 246 High-precision constant.
E() 250 High-precision constant.

String module (mpl::System::String)

Source: CppImpl.h:259-315

inline std::string Trim(const std::string& s) {
    const auto start = s.find_first_not_of(" \t\r\n");
    if (start == std::string::npos) return "";
    const auto end = s.find_last_not_of(" \t\r\n");
    return s.substr(start, end - start + 1);
}

inline std::string ToLower(const std::string& s) {
    std::string result = s;
    for (auto& c : result) {
        c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
    }
    return result;
}

inline std::string ToUpper(const std::string& s) {
    std::string result = s;
    for (auto& c : result) {
        c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
    }
    return result;
}

inline bool StartsWith(const std::string& s, const std::string& prefix) {
    return s.rfind(prefix, 0) == 0;
}

inline bool EndsWith(const std::string& s, const std::string& suffix) {
    if (suffix.size() > s.size()) return false;
    return s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0;
}

inline std::vector<std::string> Split(const std::string& s, const std::string& delimiter) {
    std::vector<std::string> result;
    size_t start = 0;
    size_t end = s.find(delimiter);
    while (end != std::string::npos) {
        result.push_back(s.substr(start, end - start));
        start = end + delimiter.size();
        end = s.find(delimiter, start);
    }
    result.push_back(s.substr(start));
    return result;
}

inline std::string Join(const std::vector<std::string>& parts, const std::string& delimiter) {
    if (parts.empty()) return "";
    std::string result = parts[0];
    for (size_t i = 1; i < parts.size(); ++i) {
        result += delimiter + parts[i];
    }
    return result;
}
Function Line Notes
Trim(s) 261 Strips ASCII whitespace (' ', '\t', '\r', '\n'). Returns "" for all-whitespace input.
ToLower(s) 268 Uses unsigned char cast to avoid UB on signed char.
ToUpper(s) 276 Same.
StartsWith(s, prefix) 284 Uses rfind(prefix, 0) == 0 idiom.
EndsWith(s, suffix) 288 Length-checks then compares tail.
Split(s, delimiter) 293 Empty entries preserved. Trailing empty NOT added (Python-compatible).
Join(parts, delimiter) 306 Returns "" for empty list.

DateTime module (mpl::System::DateTime)

Source: CppImpl.h:320-332

inline int64_t NowUnixMs() {
    auto now = std::chrono::system_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
}

inline int64_t NowUnixSeconds() {
    auto now = std::chrono::system_clock::now();
    return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
}
Function Line Notes
NowUnixMs() 322 Wall-clock milliseconds since 1970-01-01 UTC.
NowUnixSeconds() 327 Wall-clock seconds.

Wall clock vs. monotonic. These use std::chrono::system_clock (wall clock). For elapsed-time measurement in source programs, use mpl_run_microtasks / mpl_run_event_loop from empl.h (event-loop based). Wall-clock changes (NTP, manual changes) will affect DateTime results.


Generated vs. hand-written code

CppImpl.h is the hand-written reference implementation. The C++ backend may inline calls directly (e.g. Math.Sqrt(x)std::sqrt(x) instead of mpl::System::Math::Sqrt(x)) when the canonical implementation is a thin wrapper. See backends/cpp/CppBackend.h for the exact emission policy.

See also

  • modules.md — per-module documentation with source-language mappings
  • runtime.md — runtime utilities (process helpers, OS info, crypto UUID)
  • pqc.md — post-quantum crypto (separate module for advanced use)
  • headers.md — header hierarchy and when to include each