ARTS 2.5.11 (git: 6827797f)
mystring.h
Go to the documentation of this file.
1
10#ifndef mystring_h
11#define mystring_h
12
13#include <fast_float/fast_float.h>
14
15#include <algorithm>
16#include <charconv>
17#include <climits>
18#include <sstream>
19#include <string>
20#include <string_view>
21#include <type_traits>
22
23#include "array.h"
24#include "debug.h"
25#include "matpack_concepts.h"
26
43template <class charT>
44class my_basic_string : public std::basic_string<charT> {
45 public:
46 // Constructors:
47 my_basic_string() = default;
48
49 explicit my_basic_string(Index n, char c = ' ')
50 : std::basic_string<charT>(n, c) {}
51
52 my_basic_string(const std::basic_string<charT>& A,
53 Index pos = 0,
54 Index numpos = my_basic_string<charT>::npos) {
55 // Range checks:
56 ARTS_ASSERT(0 <= pos); // Start index must be 0 or greater 0.
57
58 if (!A.size()) return;
59
60 // cout << "A = " << A << "\n";
61 // cout << "pos = " << pos << "\n";
62 // cout << "size = " << A.size() << "\n";
63
64 ARTS_ASSERT(static_cast<typename std::basic_string<charT>::size_type>(pos) <
65 A.size());
66 // At most the last element of the original string.
67
70 ((numpos >= 0) &&
71 (static_cast<typename std::basic_string<charT>::size_type>(numpos) <=
72 (A.size() -
73 pos)))); // Number of characters to copy must be at the most the
74 // number left. -1 means all remaining characters.
75
76 // The assertions look complicated, because we have to cast pos and
77 // npos to the unsigned size type of basic string to avoid warning
78 // messages from the compiler. Both casts are save, because previous
79 // assertions check that pos and npos are positive. (The allowed
80 // case npos -1 (=my_basic_string<charT>::npos) is also handled
81 // correctly.)
82
83 std::basic_string<charT>::operator=(
84 std::basic_string<charT>(A, pos, numpos));
85 }
86
87 my_basic_string(const char* A)
88 : std::basic_string<charT>(A) { /* Nothing to do here. */
89 }
90
91 my_basic_string(const std::string_view& sv)
92 : std::basic_string<charT>(std::string(sv)) { /* Nothing to do here. */
93 }
94
95 // Insert string before all occurrences of the substring.
97 const my_basic_string<charT>& insstr) {
98 size_t searchstr_size = searchstr.size();
99 size_t insstr_size = insstr.size();
100 size_t start_pos = 0;
101
102 while (start_pos != std::string::npos) {
103 start_pos = this->find(searchstr, start_pos);
104 if (start_pos && start_pos != std::string::npos) {
105 this->insert(start_pos, insstr);
106 start_pos += searchstr_size + insstr_size;
107 }
108 }
109 }
110
111 // Split string
113 const my_basic_string<charT>& delim) const {
114 size_t pos, oldpos;
115 pos = oldpos = 0;
116 aos.resize(0);
117
118 while (oldpos < (size_t)this->nelem() &&
119 (pos = this->find(delim, oldpos)) !=
121 if (pos && pos - oldpos)
122 aos.push_back(this->substr(oldpos, pos - oldpos));
123 oldpos = pos + delim.nelem();
124 }
125
126 if (oldpos < (size_t)this->nelem()) aos.push_back(this->substr(oldpos));
127 }
128
130 void toupper() {
131 std::transform(this->begin(), this->end(), this->begin(), ::toupper);
132 }
133
134 [[nodiscard]] my_basic_string toupper() const {
135 my_basic_string s = *this;
136 s.toupper();
137 return s;
138 }
139
141 void tolower() {
142 std::transform(this->begin(), this->end(), this->begin(), ::tolower);
143 }
144
145 [[nodiscard]] my_basic_string tolower() const {
146 my_basic_string s = *this;
147 s.tolower();
148 return s;
149 }
150
152 void trim() {
153 // Create ref to self for readability
154 my_basic_string& this_string = *this;
155
156 // Remove leading whitespace
157 while (0 != this_string.nelem() &&
158 (' ' == this_string[0] || '\t' == this_string[0] ||
159 '\n' == this_string[0] || '\r' == this_string[0]))
160 this_string.erase(0, 1);
161
162 // Remove trailing whitespace
163 while (0 != this_string.nelem() &&
164 (' ' == this_string[this_string.nelem() - 1] ||
165 '\t' == this_string[this_string.nelem() - 1] ||
166 '\n' == this_string[this_string.nelem() - 1] ||
167 '\r' == this_string[this_string.nelem() - 1]))
168 this_string.erase(this_string.nelem() - 1);
169 }
170
171 // Number of elements:
172 [[nodiscard]] Index nelem() const {
173 size_t s = this->size();
174 ARTS_ASSERT(s < LONG_MAX);
175 return static_cast<long>(s);
176 }
177
178 // Index operators:
179 char operator[](Index n) const {
180 ARTS_ASSERT(0 <= n);
181 ARTS_ASSERT(n < nelem());
182 return std::basic_string<charT>::operator[](n);
183 }
184
185 char& operator[](Index n) {
186 ARTS_ASSERT(0 <= n);
187 ARTS_ASSERT(n < nelem());
188 return std::basic_string<charT>::operator[](n);
189 }
190
192 static const Index npos = static_cast<Index>(std::basic_string<charT>::npos);
193
194 using size_type = Index;
195};
196
200
203
206
215template <class T>
216void extract(T& x, String& line, std::size_t n) {
217 // Initialize output to zero! This is important, because otherwise
218 // the output variable could `remember' old values.
219 x = T(0);
220
221 const std::size_t N = n;
222 std::size_t i = 0;
223 while (i < N and i < line.size() and isspace(line[i])) ++i;
224 while (n > i and (n-1) < line.size() and isspace(line[n-1])) --n;
225
226 if constexpr (std::is_same_v<double, T> or std::is_same_v<float, T>) {
227 fast_float::from_chars(line.data() + i, line.data() + n, x);
228 } else if constexpr (std::is_same_v<long long, T> or
229 std::is_same_v<long, T> or std::is_same_v<int, T>) {
230 std::from_chars(line.data() + i, line.data() + n, x);
231 } else {
232 // This will contain the short subString with the item to extract.
233 // Make it a String stream, for easy parsing,
234 // extracting subString of width n from line:
235 std::istringstream item(line.substr(i, n));
236
237 // Convert with the aid of String stream item:
238 item >> x;
239 }
240
241 // Shorten line by n:
242 line.erase(0, N);
243}
244
245//Specialize std::hash for String (this is allowed by the standard)
246namespace std {
247 template <> struct hash<String>
248 {
249 size_t operator()(const String & x) const
250 {
251 return hash<string>{}(x);
252 }
253 };
254}
255
256#endif // mystring_h
This file contains the definition of Array.
This can be used to make arrays out of anything.
Definition: array.h:31
The implementation for String, the ARTS string class.
Definition: mystring.h:44
char & operator[](Index n)
Definition: mystring.h:185
my_basic_string(Index n, char c=' ')
Definition: mystring.h:49
char operator[](Index n) const
Definition: mystring.h:179
void insert_substr(const my_basic_string< charT > &searchstr, const my_basic_string< charT > &insstr)
Definition: mystring.h:96
Index nelem() const
Definition: mystring.h:172
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Definition: mystring.h:112
my_basic_string()=default
my_basic_string tolower() const
Definition: mystring.h:145
Index size_type
Definition: mystring.h:194
void trim()
Trim leading and trailing whitespace.
Definition: mystring.h:152
static const Index npos
Define npos:
Definition: mystring.h:192
my_basic_string toupper() const
Definition: mystring.h:134
void toupper()
Convert to upper case.
Definition: mystring.h:130
my_basic_string(const std::basic_string< charT > &A, Index pos=0, Index numpos=my_basic_string< charT >::npos)
Definition: mystring.h:52
my_basic_string(const char *A)
Definition: mystring.h:87
my_basic_string(const std::string_view &sv)
Definition: mystring.h:91
void tolower()
Convert to lower case.
Definition: mystring.h:141
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
Definition: debug.h:84
void extract(T &x, String &line, std::size_t n)
Extract something from the beginning of a string.
Definition: mystring.h:216
Definition: mystring.h:246
size_t operator()(const String &x) const
Definition: mystring.h:249
#define c