C++ Utilities
Loading...
Searching...
No Matches
stream.h
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: 2025 Nessan Fitzmaurice <nzznfitz+gh@icloud.com>
3// SPDX-License-Identifier: MIT
4
8
9#include <iostream>
10#include <string>
11
12namespace utilities {
13
22static std::size_t
23read_line(std::istream& s, std::string& line, std::string_view comment_begin = "#")
24{
25 // Lambda that trims a string in-place from leading/trailing space characters.
26 auto trim = [](std::string& str) {
27 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](int ch) { return !std::isspace(ch); }));
28 str.erase(std::find_if(str.rbegin(), str.rend(), [](int ch) { return !std::isspace(ch); }).base(), str.end());
29 };
30
31 // Zap any existing content in the output parameter.
32 line.clear();
33
34 // We keep trying to read content until we hit the end-of-file (there are other early exits below).
35 while (!s.eof()) {
36
37 // Standard read-a-line from a stream.
38 std::getline(s, line);
39
40 // Remove any trailing comment (starts with the comment_begin).
41 if (!comment_begin.empty()) {
42 auto begin = line.find_first_of(comment_begin);
43 if (begin != std::string::npos) line.erase(begin, line.length() - begin);
44 }
45
46 // Remove leading & trailing blanks.
47 trim(line);
48
49 // If after all that we haven't captured anything skip on to try the next line.
50 std::size_t n = line.length();
51 if (n == 0) continue;
52
53 // Handle continuation lines (we know that n != 0).
54 if (line[n - 1] == '\\') {
55 // Replace the continuation character with a space
56 line[n - 1] = ' ';
57
58 // Trim--we'll add one space back if there is a non-empty continuation.
59 trim(line);
60
61 // Recurse ...
62 std::string continuation;
63 read_line(s, continuation, comment_begin);
64 if (!continuation.empty()) {
65 line += " ";
66 line += continuation;
67 }
68 }
69
70 // If we have captured some content in `line` we can go home.
71 if (!line.empty()) break;
72 }
73
74 return line.length();
75}
76
85inline std::string
86read_line(std::istream& s, std::string_view comment_begin = "#")
87{
88 std::string retval;
89 read_line(s, retval, comment_begin);
90 return retval;
91}
92
94inline std::istream&
95rewind(std::istream& is)
96{
97 is.clear();
98 is.seekg(0, std::istream::beg);
99 return is;
100}
101
105inline std::size_t
106line_count(std::istream& is, std::string_view comment_begin = "#")
107{
108 std::size_t retval = 0;
109 std::string line;
110 if (comment_begin.empty()) {
111 while (std::getline(is, line)) ++retval;
112 }
113 else {
114 while (read_line(is, line, comment_begin)) ++retval;
115 }
116 rewind(is);
117 return retval;
118}
119
120} // namespace utilities
The namespace for the utilities library.
Definition formatter.h:14
std::size_t line_count(std::istream &is, std::string_view comment_begin="#")
Counts the number of lines in the input stream.
Definition stream.h:106
std::istream & rewind(std::istream &is)
Rewind an input stream to the start.
Definition stream.h:95
void trim(std::string &str)
Removes all leading & trailing white-space from a string in-place.
Definition string.h:137