Pioneer
Loading...
Searching...
No Matches
StringUtils.h
Go to the documentation of this file.
1// Copyright © 2008-2024 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#pragma once
5
6#include <cstring>
7#include <string>
8#include <string_view>
9#include <vector>
10#include <iterator>
11#include <cstdint>
12
13#ifdef _MSC_VER
14#ifndef __MINGW32__
15#define strncasecmp _strnicmp
16#define strcasecmp _stricmp
17#endif
18#endif
19
20// Pioneer String Utility Helpers
21
22#define SIZET_FMT "%zu"
23
24std::string format_date(double time);
25std::string format_date_only(double time);
26std::string format_distance(double dist, int precision = 2);
27std::string format_money(double cents, bool showCents = true);
28std::string format_duration(double seconds);
29
30// find string in bigger string, ignoring case
31const char *pi_strcasestr(const char *haystack, const char *needle);
32
33inline bool starts_with(const std::string_view s, const std::string_view t)
34{
35 if (s.size() < t.size())
36 return false;
37 return std::memcmp(s.data(), t.data(), t.size()) == 0;
38}
39
40inline bool ends_with(const std::string_view s, const std::string_view t)
41{
42 if (s.size() < t.size())
43 return false;
44
45 return std::memcmp(s.data() + (s.size() - t.size()), t.data(), t.size()) == 0;
46}
47
48inline bool starts_with_ci(const std::string_view s, const std::string_view t)
49{
50 if (s.size() < t.size())
51 return false;
52
53 for (size_t i = 0; i < t.size(); i++)
54 if (tolower(s.data()[i]) != tolower(t.data()[i]))
55 return false;
56
57 return true;
58}
59
60inline bool ends_with_ci(const std::string_view s, const std::string_view t)
61{
62 if (s.size() < t.size())
63 return false;
64
65 for (int64_t i = t.size(); i > 0; i--)
66 if (tolower(s.data()[s.size() - i]) != tolower(t.data()[t.size() - i]))
67 return false;
68
69 return true;
70}
71
72inline bool compare_ci(const std::string_view s, const std::string_view t)
73{
74 if (s.size() != t.size())
75 return false;
76
77 for (size_t i = 0; i < s.size(); i++)
78 if (tolower(s.data()[i]) != tolower(t.data()[i]))
79 return false;
80
81 return true;
82}
83
84inline std::string_view read_line(std::string_view &s)
85{
86 if (s.empty())
87 return {};
88
89 std::string_view out = s;
90
91 size_t end = s.find_first_of("\r\n");
92 if (end == std::string_view::npos) {
93 s = {};
94 return out;
95 }
96
97 out = { s.data(), end };
98
99 size_t start = s.find_first_not_of("\r\n", end);
100 if (start == std::string_view::npos) {
101 s = {};
102 return out;
103 }
104
105 s.remove_prefix(start);
106 return out;
107}
108
109inline std::string_view strip_spaces(std::string_view &s)
110{
111 if (s.empty())
112 return s;
113
114 size_t start = s.find_first_not_of(" \t\r\n\v");
115 if (start == std::string::npos)
116 return {};
117
118 size_t end = s.find_last_not_of(" \t\r\n\v");
119
120 return s.substr(start, end);
121}
122
123// Utility class to split a string based on a provided set of delimiters
124// Makes find_first_of / find_last_of more ergonomic to use
126 struct iter {
127 using value_type = std::string_view;
128 using reference = std::string_view;
129
130 // "end" iterator
131 iter() : m_parent(nullptr), m_str() {};
132 // "live" iterator
133 iter(SplitString *parent) :
134 m_parent(parent),
135 m_str(parent->m_orig),
136 m_next(parent->step(m_str))
137 {
138 }
139
141 {
142 if (m_next != std::string_view::npos)
143 return m_parent->m_reverse ? m_str.substr(m_next + 1) : m_str.substr(0, m_next);
144 else
145 return m_str;
146 }
147
149 {
150 m_parent->trim(m_str, m_next);
151 m_next = m_parent->step(m_str);
152 return *this;
153 }
154
155 bool operator!=(const iter &rhs) { return !(*this == rhs); }
156 bool operator==(const iter &rhs) {
157 return (m_str.empty() && rhs.m_str.empty()) ||
158 (m_parent == rhs.m_parent && m_str.size() == rhs.m_str.size());
159 }
160
161 private:
162 SplitString *m_parent;
163 std::string_view m_str;
164 size_t m_next = std::string_view::npos;
165 };
166
167 SplitString(std::string_view source, std::string_view delim) :
168 m_orig(source), m_delim(delim)
169 {}
170
171 SplitString(std::string_view source, std::string_view delim, bool reverse) :
172 m_orig(source), m_delim(delim), m_reverse(reverse)
173 {}
174
175 iter begin() { return iter(this); }
176 iter end() { return iter(); }
177
178 // Split the input string to a vector of fragments using the specified type
179 template<typename T = std::string_view>
180 std::vector<T> to_vector() {
181 std::vector<T> out;
182 for (auto str : *this) {
183 out.push_back(T(str));
184 }
185
186 return out;
187 }
188
189 // Apply the given predicate to each fragment of the string and push the result into the given container
190 template<typename Container, typename Predicate>
191 void to_vector(Container &c, Predicate p) {
192 for (auto str : *this) {
193 c.push_back(p(str));
194 }
195 }
196
197private:
198 friend struct iter;
199
200 // find the boundary for the next token
201 size_t step(std::string_view str);
202 // remove previous substring if present
203 void trim(std::string_view &str, size_t next);
204
205 std::string_view m_orig;
206 std::string_view m_delim;
207 bool m_reverse = false;
208};
209
210// 'Numeric type' to string conversions.
211std::string FloatToStr(float val);
212std::string DoubleToStr(double val);
213std::string AutoToStr(int32_t val);
214std::string AutoToStr(int64_t val);
215std::string AutoToStr(float val);
216std::string AutoToStr(double val);
217
218// String to 'Numeric type' conversions.
219int64_t StrToSInt64(const std::string &str);
220uint64_t StrToUInt64(const std::string &str);
221float StrToFloat(const std::string &str);
222double StrToDouble(const std::string &str);
223void StrToAuto(int32_t *pVal, const std::string &str);
224void StrToAuto(int64_t *pVal, const std::string &str);
225void StrToAuto(float *pVal, const std::string &str);
226void StrToAuto(double *pVal, const std::string &str);
227
228// Convert decimal coordinates to degree/minute/second format and return as string
229std::string DecimalToDegMinSec(float dec);
double val
Definition: PrecalcPath.cpp:40
float StrToFloat(const std::string &str)
Definition: StringUtils.cpp:274
bool compare_ci(const std::string_view s, const std::string_view t)
Definition: StringUtils.h:72
std::string format_date_only(double time)
Definition: StringUtils.cpp:81
bool ends_with(const std::string_view s, const std::string_view t)
Definition: StringUtils.h:40
uint64_t StrToUInt64(const std::string &str)
Definition: StringUtils.cpp:267
std::string AutoToStr(int32_t val)
bool starts_with(const std::string_view s, const std::string_view t)
Definition: StringUtils.h:33
bool ends_with_ci(const std::string_view s, const std::string_view t)
Definition: StringUtils.h:60
int64_t StrToSInt64(const std::string &str)
Definition: StringUtils.cpp:260
std::string_view read_line(std::string_view &s)
Definition: StringUtils.h:84
std::string format_money(double cents, bool showCents=true)
Definition: StringUtils.cpp:15
std::string FloatToStr(float val)
Definition: StringUtils.cpp:206
bool starts_with_ci(const std::string_view s, const std::string_view t)
Definition: StringUtils.h:48
std::string format_date(double time)
Definition: StringUtils.cpp:68
std::string format_duration(double seconds)
Definition: StringUtils.cpp:105
void StrToAuto(int32_t *pVal, const std::string &str)
std::string_view strip_spaces(std::string_view &s)
Definition: StringUtils.h:109
std::string format_distance(double dist, int precision=2)
Definition: StringUtils.cpp:129
const char * pi_strcasestr(const char *haystack, const char *needle)
Definition: StringUtils.cpp:157
double StrToDouble(const std::string &str)
Definition: StringUtils.cpp:291
std::string DoubleToStr(double val)
Definition: StringUtils.cpp:221
std::string DecimalToDegMinSec(float dec)
Definition: StringUtils.cpp:333
Definition: StringUtils.h:126
iter & operator++()
Definition: StringUtils.h:148
iter(SplitString *parent)
Definition: StringUtils.h:133
bool operator==(const iter &rhs)
Definition: StringUtils.h:156
iter()
Definition: StringUtils.h:131
bool operator!=(const iter &rhs)
Definition: StringUtils.h:155
std::string_view value_type
Definition: StringUtils.h:127
std::string_view reference
Definition: StringUtils.h:128
value_type operator*()
Definition: StringUtils.h:140
Definition: StringUtils.h:125
iter begin()
Definition: StringUtils.h:175
SplitString(std::string_view source, std::string_view delim)
Definition: StringUtils.h:167
void to_vector(Container &c, Predicate p)
Definition: StringUtils.h:191
std::vector< T > to_vector()
Definition: StringUtils.h:180
iter end()
Definition: StringUtils.h:176
SplitString(std::string_view source, std::string_view delim, bool reverse)
Definition: StringUtils.h:171