CPP-snippets 0.0.1
A silly C++ project to use for demonstrating code integration
Loading...
Searching...
No Matches
IOInterface Class Reference

#include <interface.hpp>

Public Member Functions

 IOInterface (int argc, char *argv[])
 Construct a new Interface and load the TOML configuration file.
 
template<typename Derived>
void write2csv (const std::string &filename, const Eigen::MatrixBase< Derived > &mat_data, const std::string &comment) const
 Write a matrix to a CSV file in scientific notation.
 
void write2csv (const std::string &filename, Eigen::VectorXd &vector_data, const std::string &comment) const
 
template<typename VecT>
VecT load_vector (const std::string &toml_path) const
 
template<typename T>
load_scalar (const std::string &toml_path) const
 Load a scalar value from the TOML input file using a dotted path.
 

Data Fields

toml::table m_input
 

Detailed Description

Parameters
m_output_dirOutput directory based on toml input

Definition at line 15 of file interface.hpp.

Constructor & Destructor Documentation

◆ IOInterface()

IOInterface ( int argc,
char * argv[] )
explicit

Construct a new Interface and load the TOML configuration file.

Expects the first command-line argument (argv[1]) to be the path to the TOML configuration file.

Parameters
argcNumber of command-line arguments.
argvCommand-line argument array.

Definition at line 6 of file interface.cpp.

6 {
7
8 std::cout << " -> Initializing Interface ..." << std::endl;
9 if (argc != 1){
10 try {
11 if (!std::filesystem::exists(argv[1])) {
12 std::cerr << "[Interface] Config file not found: " << argv[1] << '\n';
13 }
14 m_input = toml::parse_file(argv[1]);
15 std::cout << "### Settings from TOML: ###\n" << m_input << std::endl;
16 }
17 catch (const toml::parse_error& err) {
18 std::cerr << "[Interface] Parse error: " << err.description()
19 << "\n at " << err.source().begin << '\n';
20 }
21 } else {
22 throw std::runtime_error("Usage: <program> <config.toml>");
23 }
24 // --- Create output directory on initialization ---
25 std::filesystem::path output_dir = m_input.get("output")->value_or("");
26 try {
27 if (!output_dir.empty()) {
28 std::filesystem::create_directories(output_dir);
29 std::cout << " -> Output directory ready: " << output_dir << std::endl;
30 }
31 else {
32 throw std::runtime_error("No output directory defined in config.toml");
33 }
34 }
35 catch (const std::filesystem::filesystem_error& e) {
36 throw std::runtime_error(
37 "Failed to create output directory '" + output_dir.string() + "': " + e.what()
38 );
39 }
40};

◆ ~IOInterface()

Definition at line 56 of file interface.cpp.

56 {
57 try {
58 std::filesystem::path output_dir = m_input.get("output")->value_or("");
59
60 if (output_dir.empty()) {
61 std::cerr << "[Interface] No output directory, cannot write config_used.toml\n";
62 return;
63 }
64
65 std::filesystem::path out_file = output_dir / "config_used.toml";
66 std::ofstream os(out_file);
67
68 if (!os.is_open()) {
69 std::cerr << "[Interface] Failed to write config_used.toml\n";
70 return;
71 }
72
73 os << m_input << "\n"; // toml++ automatically formats the table
74 os.close();
75
76 std::cout << " -> Wrote config_used.toml to " << out_file << std::endl;
77 }
78 catch (const std::exception& e) {
79 std::cerr << "[Interface] Error writing config_used.toml: " << e.what() << "\n";
80 }
81}

Member Function Documentation

◆ load_scalar()

template<typename T>
T load_scalar ( const std::string & toml_path) const
inline

Load a scalar value from the TOML input file using a dotted path.

This function loads a single scalar value (int, double, bool, string, …) from the TOML configuration. The path is resolved using toml::node::at_path().

Template Parameters
TThe C++ type to convert the TOML value into.
Parameters
toml_pathDotted path to the value in the TOML configuration.
Returns
The loaded value, converted to type T.
Exceptions
std::runtime_errorif the path does not exist or cannot be converted.

Definition at line 134 of file interface.hpp.

135 {
136 // Try to access the node at the given path
137 auto node = m_input.at_path(toml_path);
138
139 if (!node) {
140 throw std::runtime_error("Missing scalar value at path: " + toml_path);
141 }
142
143 // Extract the value and convert
144 auto val = node.value<T>();
145 if (!val.has_value()) {
146 throw std::runtime_error(
147 "Type mismatch or invalid value at path: " + toml_path
148 );
149 }
150
151 return *val;
152 }

◆ load_vector()

template<typename VecT>
VecT load_vector ( const std::string & toml_path) const
inline

Definition at line 85 of file interface.hpp.

86 {
87 using Scalar = typename VecT::Scalar;
88
89 // Access array in TOML
90 auto arr = m_input.at_path(toml_path).as_array();
91 if (!arr) {
92 throw std::runtime_error("Missing " + toml_path + " array in TOML file.");
93 }
94
95 const std::size_t toml_size = arr->size();
96 // Create resulting vector
97 VecT vec;
98
99 // Handle fixed-size vs dynamic-size
100 if constexpr (VecT::SizeAtCompileTime == Eigen::Dynamic) {
101 vec.resize(toml_size);
102 } else {
103 if (toml_size != VecT::SizeAtCompileTime) {
104 throw std::runtime_error(
105 "Size mismatch for " + toml_path +
106 ": expected " + std::to_string(VecT::SizeAtCompileTime) +
107 ", got " + std::to_string(toml_size)
108 );
109 }
110 }
111
112 // Fill vector
113 for (std::size_t i = 0; i < toml_size; ++i) {
114 vec(i) = static_cast<Scalar>(arr->at(i).value_or(Scalar{}));
115 }
116
117 return vec;
118 }

◆ write2csv() [1/2]

template<typename Derived>
void write2csv ( const std::string & filename,
const Eigen::MatrixBase< Derived > & mat_data,
const std::string & comment ) const
inline

Write a matrix to a CSV file in scientific notation.

This method exports the content of an Eigen::MatrixXd to a CSV-formatted text file. Each row of the matrix is written as a line in the file, with values formatted using scientific notation. The output file will be overwritten if it already exists.

Parameters
filenameThe path and name of the output CSV file.
matrix_dataThe matrix whose contents will be written to the file. Each row is written sequentially as a separate line.
Note
  • Values are written using std::scientific formatting.
  • No header row is included in the output.
  • Elements in each row are written using Eigen’s default stream operator, which separates values with spaces rather than commas unless customized.
See also
Eigen::MatrixXd

Definition at line 55 of file interface.hpp.

57 {
58
59 std::filesystem::path output_dir = m_input.get("output")->value_or("");
60
61 std::cout << " Writing " << filename << std::endl;
62
63 std::ofstream output_stream(output_dir / filename);
64 if (!output_stream.is_open()) {
65 throw std::runtime_error("Cannot open file: " +
66 (output_dir / filename).string());
67 }
68
69 output_stream << std::scientific;
70 const int rows = mat_data.rows();
71 const int cols = mat_data.cols();
72 output_stream << "# Data size (" << rows << ", " << cols << ")" << comment << std::endl;
73
74 for (int i = 0; i < rows; ++i) {
75 for (int j = 0; j < cols; ++j) {
76 output_stream << mat_data(i, j);
77 if (j < cols - 1) output_stream << ' '; // single whitespace
78 }
79 output_stream << '\n';
80 }
81 }

◆ write2csv() [2/2]

void write2csv ( const std::string & filename,
Eigen::VectorXd & vector_data,
const std::string & comment ) const

Definition at line 42 of file interface.cpp.

42 {
43 std::cout << " Writing " << filename << std::endl;
44
45 std::filesystem::path output_dir = m_input.get("output")->value_or("");
46 std::ofstream output_stream(output_dir / filename);
47
48 if (!output_stream.is_open()) {
49 throw std::runtime_error("Cannot open file: " + (output_dir / filename).string());
50 }
51
52 output_stream << "# data length " << vector_data.size() << comment << std::endl;
53 output_stream << std::scientific << vector_data << '\n';
54}

Field Documentation

◆ m_input

toml::table m_input

Definition at line 17 of file interface.hpp.


The documentation for this class was generated from the following files: