ampsci
High-precision calculations for one- and two-valence atomic systems
FRW_fileReadWrite.hpp
1#pragma once
2#include <algorithm>
3#include <fstream>
4#include <iostream>
5#include <sstream>
6#include <string>
7#include <tuple>
8#include <type_traits>
9#include <utility>
10#include <vector>
11/*!
12 @brief File read/write utilities: text parsing and binary I/O.
13 @details
14 Low-level helpers for reading and writing text and binary files. Includes
15 functions for parsing space- or line-separated input files (with comment
16 stripping), reading (x, y) data, and variadic binary read/write for PoD types,
17 vectors, and strings.
18
19 @warning Many functions in this namespace are old and some are obsolete.
20 Use sparingly and with caution -- prefer higher-level IO interfaces where
21 available.
22*/
23namespace IO::FRW {
24
25//------------------------------------------------------------------------------
26//! Reads (x, y) pairs from a file; returns a pair of vectors {xs, ys}.
27//! Lines beginning with '#', '!', or '//' are skipped.
28inline std::pair<std::vector<double>, std::vector<double>>
29readFile_xy_PoV(const std::string &fname) {
30 std::pair<std::vector<double>, std::vector<double>> out_list;
31 std::ifstream file(fname);
32 std::string line = "";
33 while (getline(file, line) && (file.is_open())) { // redundant?
34 if (line == "")
35 continue;
36 if (line.at(0) == '!' || line.at(0) == '#')
37 continue;
38 if (line.size() >= 2 && line.at(0) == '/' && line.at(1) == '/')
39 continue;
40 std::stringstream ss(line);
41 double x, y;
42 ss >> x >> y;
43 out_list.first.push_back(x);
44 out_list.second.push_back(y);
45 }
46 return out_list;
47}
48
49//==============================================================================
50//! Removes C-style block comments (/* ... */) from a string in-place.
51inline void removeBlockComments(std::string &input) {
52 for (auto posi = input.find("/*"); posi != std::string::npos;
53 posi = input.find("/*")) {
54 auto posf = input.find("*/");
55 if (posf != std::string::npos) {
56 input = input.substr(0, posi) + input.substr(posf + 2);
57 } else {
58 input = input.substr(0, posi);
59 }
60 }
61}
62//==============================================================================
63//! Strips comments (#, !, //, /* */), spaces, tabs, and quote characters.
64//! Lines are squashed together; semicolons are preserved as delimiters.
65inline std::string removeCommentsAndSpaces(const std::string &input) {
66 std::string lines = "";
67 {
68 std::string line;
69 std::stringstream stream1(input);
70 while (std::getline(stream1, line, '\n')) {
71 auto comm1 = line.find('!'); // nb: char, NOT string literal!
72 auto comm2 = line.find('#');
73 auto comm3 = line.find("//"); // str literal here
74 auto comm = std::min(comm1, std::min(comm2, comm3));
75 lines += line.substr(0, comm);
76 }
77 }
78
80
81 // remove spaces
82 lines.erase(std::remove_if(lines.begin(), lines.end(),
83 [](unsigned char x) { return x == ' '; }),
84 lines.end());
85 // remove tabs
86 lines.erase(std::remove_if(lines.begin(), lines.end(),
87 [](unsigned char x) { return x == '\t'; }),
88 lines.end());
89
90 // remove ' and "
91 lines.erase(std::remove_if(lines.begin(), lines.end(),
92 [](unsigned char x) { return x == '\''; }),
93 lines.end());
94 lines.erase(std::remove_if(lines.begin(), lines.end(),
95 [](unsigned char x) { return x == '\"'; }),
96 lines.end());
97
98 return lines;
99}
100
101//==============================================================================
102enum RoW { read, write, update };
103
104// XXX Wrap these into a class. AND make explicit which types are/aren't
105// allowed!
106
107//! Opens a binary fstream for reading or writing according to @p row.
108//! @p update opens existing file for random-access read/write without truncation.
109inline void open_binary(std::fstream &stream, const std::string &fname,
110 RoW row) {
111 switch (row) {
112 case write:
113 stream.open(fname, std::ios_base::out | std::ios_base::binary);
114 break;
115 case read:
116 stream.open(fname, std::ios_base::in | std::ios_base::binary);
117 break;
118 case update:
119 stream.open(fname,
120 std::ios_base::in | std::ios_base::out | std::ios_base::binary);
121 break;
122 default:
123 std::cout << "\nFAIL 16 in FRW\n";
124 }
125}
126
127//! Returns true if the file at @p fileName exists and can be opened.
128inline bool file_exists(const std::string &fileName) {
129 if (fileName == "")
130 return false;
131 std::ifstream infile(fileName);
132 return infile.good();
133}
134
135//! Function (variadic): reads/writes data from/to binary file. Works for
136//! trivial (PoD) types, and std::string only (but not checked)
137//! Overload for vectors
138template <typename T, typename... Types>
139void rw_binary(std::fstream &stream, RoW row, std::vector<T> &value,
140 Types &...values) {
141 binary_rw_vec(stream, value, row);
142 if constexpr (sizeof...(values) != 0)
143 rw_binary(stream, row, values...);
144}
145
146//! Function (variadic): reads/writes data from/to binary file. Works for
147//! trivial (PoD) types, and std::string only (but not checked)
148template <typename T, typename... Types>
149void rw_binary(std::fstream &stream, RoW row, T &value, Types &...values) {
150 if constexpr (std::is_same_v<T, std::string>)
151 binary_str_rw(stream, value, row);
152 else
153 binary_rw(stream, value, row);
154 if constexpr (sizeof...(values) != 0)
155 rw_binary(stream, row, values...);
156}
157
158// make "private" behind 'helper' namespace: used in old code still
159template <typename T>
160void binary_rw(std::fstream &stream, T &value, RoW row) {
161 switch (row) {
162 case write:
163 stream.write(reinterpret_cast<const char *>(&value), sizeof(T));
164 break;
165 case read:
166 stream.read(reinterpret_cast<char *>(&value), sizeof(T));
167 break;
168 default:
169 std::cout << "\nFAIL 32 in FRW\n";
170 }
171}
172
173// For vector. {works with Vector of vectors also}
174template <typename T>
175void binary_rw_vec(std::fstream &stream, std::vector<T> &value, RoW row) {
176 std::size_t size = value.size();
177 binary_rw(stream, size, row);
178 if (row == read)
179 value.resize(size);
180 for (auto &x : value) {
181 rw_binary(stream, row, x);
182 }
183}
184
185// make "private" behind 'helper' namespace: used in old code still
186inline void binary_str_rw(std::fstream &stream, std::string &value, RoW row) {
187 if (row == write) {
188 std::size_t temp_len = value.length();
189 stream.write(reinterpret_cast<const char *>(&temp_len),
190 sizeof(std::size_t));
191 stream.write(value.c_str(), long(value.length()));
192 } else if (row == read) {
193 std::size_t temp_len;
194 stream.read(reinterpret_cast<char *>(&temp_len), sizeof(std::size_t));
195 char *tvalue = new char[temp_len + 1];
196 stream.read(tvalue, long(temp_len));
197 tvalue[temp_len] = '\0'; // null 'end of string' character
198 value = tvalue;
199 delete[] tvalue;
200 } else {
201 std::cout << "\nFAIL 55 in FRW\n";
202 }
203}
204
205} // namespace IO::FRW
File read/write utilities: text parsing and binary I/O.
Definition FRW_fileReadWrite.hpp:23
std::pair< std::vector< double >, std::vector< double > > readFile_xy_PoV(const std::string &fname)
Reads (x, y) pairs from a file; returns a pair of vectors {xs, ys}. Lines beginning with '#',...
Definition FRW_fileReadWrite.hpp:29
void rw_binary(std::fstream &stream, RoW row, std::vector< T > &value, Types &...values)
Function (variadic): reads/writes data from/to binary file. Works for trivial (PoD) types,...
Definition FRW_fileReadWrite.hpp:139
void open_binary(std::fstream &stream, const std::string &fname, RoW row)
Opens a binary fstream for reading or writing according to row. update opens existing file for random...
Definition FRW_fileReadWrite.hpp:109
bool file_exists(const std::string &fileName)
Returns true if the file at fileName exists and can be opened.
Definition FRW_fileReadWrite.hpp:128
std::string removeCommentsAndSpaces(const std::string &input)
Strips comments (#, !, //, /* *‍/), spaces, tabs, and quote characters. Lines are squashed together; ...
Definition FRW_fileReadWrite.hpp:65
void removeBlockComments(std::string &input)
Removes C-style block comments (/* ... *‍/) from a string in-place.
Definition FRW_fileReadWrite.hpp:51