Pioneer
utils.h
Go to the documentation of this file.
1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _UTILS_H
5 #define _UTILS_H
6 
7 #if defined(_MSC_VER) && !defined(NOMINMAX)
8 #define NOMINMAX
9 #endif
10 
11 #include "core/Log.h"
12 #include "libs.h"
13 #include <fmt/printf.h>
14 #include <stdarg.h>
15 #include <stdio.h>
16 #include <string>
17 #include <vector>
18 
19 #ifndef __GNUC__
20 #define __attribute(x)
21 #endif /* __GNUC__ */
22 
23 // GCC warns when a function marked __attribute((noreturn)) actually returns a value
24 // but other compilers which don't see the noreturn attribute of course require that
25 // a function with a non-void return type should return something.
26 #ifndef __GNUC__
27 #define RETURN_ZERO_NONGNU_ONLY return 0;
28 #else
29 #define RETURN_ZERO_NONGNU_ONLY
30 #endif
31 
32 // align x to a. taken from the Linux kernel
33 #define ALIGN(x, a) __ALIGN_MASK(x, (a - 1))
34 #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
35 
36 // void Error(const char *format, ...) __attribute((format(printf, 1, 2))) __attribute((noreturn));
37 // void Warning(const char *format, ...) __attribute((format(printf, 1, 2)));
38 // void Output(const char *format, ...) __attribute((format(printf, 1, 2)));
39 
40 template <typename... Args>
41 inline void Output(const char *message, Args... args)
42 {
43  Log::LogOld(Log::Severity::Info, fmt::sprintf(message, args...));
44 }
45 
46 template <typename... Args>
47 inline void Warning(const char *message, Args... args)
48 {
49  Log::LogOld(Log::Severity::Warning, fmt::sprintf(message, args...));
50 }
51 
52 template <typename... Args>
53 [[noreturn]] inline void Error(const char *message, Args... args)
54 {
55  Log::LogFatalOld(fmt::sprintf(message, args...));
56 }
57 
58 template <typename... Args>
59 inline void DebugMsg(const char *message, Args... args)
60 {
61  Log::LogOld(Log::Severity::Debug, fmt::sprintf(message, args...));
62 }
63 
64 std::string string_join(std::vector<std::string> &v, std::string sep);
65 std::string format_date(double time);
66 std::string format_date_only(double time);
67 std::string format_distance(double dist, int precision = 2);
68 std::string format_money(double cents, bool showCents = true);
69 std::string format_duration(double seconds);
70 
71 static inline Sint64 isqrt(Sint64 a)
72 {
73  // replace with cast from sqrt below which is between x7.3 (win32, Debug) & x15 (x64, Release) times faster
74  return static_cast<int64_t>(sqrt(static_cast<double>(a)));
75 }
76 
77 static inline Sint64 isqrt(fixed v)
78 {
79  Sint64 ret = 0;
80  Sint64 s;
81  Sint64 ret_sq = -v.v - 1;
82  for (s = 62; s >= 0; s -= 2) {
83  Sint64 b;
84  ret += ret;
85  b = ret_sq + ((2 * ret + 1) << s);
86  if (b < 0) {
87  ret_sq = b;
88  ret++;
89  }
90  }
91  return ret;
92 }
93 
94 // find string in bigger string, ignoring case
95 const char *pi_strcasestr(const char *haystack, const char *needle);
96 
97 inline bool starts_with(const std::string_view s, const std::string_view t)
98 {
99  if (s.size() < t.size())
100  return false;
101  return memcmp(s.data(), t.data(), t.size()) == 0;
102 }
103 
104 inline bool ends_with(const std::string_view s, const std::string_view t)
105 {
106  if (s.size() < t.size())
107  return false;
108 
109  return memcmp(s.data() + (s.size() - t.size()), t.data(), t.size()) == 0;
110 }
111 
112 inline bool starts_with_ci(const std::string_view s, const std::string_view t)
113 {
114  if (s.size() < t.size())
115  return false;
116 
117  for (size_t i = 0; i < t.size(); i++)
118  if (tolower(s.data()[i]) != tolower(t.data()[i]))
119  return false;
120 
121  return true;
122 }
123 
124 inline bool ends_with_ci(const std::string_view s, const std::string_view t)
125 {
126  if (s.size() < t.size())
127  return false;
128 
129  for (int64_t i = t.size(); i > 0; i--)
130  if (tolower(s.data()[s.size() - i]) != tolower(t.data()[t.size() - i]))
131  return false;
132 
133  return true;
134 }
135 
136 static inline size_t SplitSpec(const std::string &spec, std::vector<int> &output)
137 {
138  static const std::string delim(",");
139 
140  size_t i = 0, start = 0, end = 0;
141  while (end != std::string::npos) {
142  // get to the first non-delim char
143  start = spec.find_first_not_of(delim, end);
144 
145  // read the end, no more to do
146  if (start == std::string::npos)
147  break;
148 
149  // find the end - next delim or end of string
150  end = spec.find_first_of(delim, start);
151 
152  // extract the fragment and remember it
153  output[i++] = atoi(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str());
154  }
155 
156  return i;
157 }
158 
159 static inline size_t SplitSpec(const std::string &spec, std::vector<float> &output)
160 {
161  static const std::string delim(",");
162 
163  size_t i = 0, start = 0, end = 0;
164  while (end != std::string::npos) {
165  // get to the first non-delim char
166  start = spec.find_first_not_of(delim, end);
167 
168  // read the end, no more to do
169  if (start == std::string::npos)
170  break;
171 
172  // find the end - next delim or end of string
173  end = spec.find_first_of(delim, start);
174 
175  // extract the fragment and remember it
176  output[i++] = atof(spec.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str());
177  }
178 
179  return i;
180 }
181 
182 std::vector<std::string> SplitString(const std::string &source, const std::string &delim);
183 
184 // 'Numeric type' to string conversions.
185 std::string FloatToStr(float val);
186 std::string DoubleToStr(double val);
187 std::string AutoToStr(Sint32 val);
188 std::string AutoToStr(Sint64 val);
189 std::string AutoToStr(float val);
190 std::string AutoToStr(double val);
191 
192 void Vector3fToStr(const vector3f &val, char *out, size_t size);
193 void Vector3dToStr(const vector3d &val, char *out, size_t size);
194 void Matrix3x3fToStr(const matrix3x3f &val, char *out, size_t size);
195 void Matrix3x3dToStr(const matrix3x3d &val, char *out, size_t size);
196 void Matrix4x4fToStr(const matrix4x4f &val, char *out, size_t size);
197 void Matrix4x4dToStr(const matrix4x4d &val, char *out, size_t size);
198 
199 // String to 'Numeric type' conversions.
200 Sint64 StrToSInt64(const std::string &str);
201 Uint64 StrToUInt64(const std::string &str);
202 float StrToFloat(const std::string &str);
203 double StrToDouble(const std::string &str);
204 void StrToAuto(Sint32 *pVal, const std::string &str);
205 void StrToAuto(Sint64 *pVal, const std::string &str);
206 void StrToAuto(float *pVal, const std::string &str);
207 void StrToAuto(double *pVal, const std::string &str);
208 
209 void StrToVector3f(const char *str, vector3f &val);
210 void StrToVector3d(const char *str, vector3d &val);
211 void StrToMatrix3x3f(const char *str, matrix3x3f &val);
212 void StrToMatrix3x3d(const char *str, matrix3x3d &val);
213 void StrToMatrix4x4f(const char *str, matrix4x4f &val);
214 void StrToMatrix4x4d(const char *str, matrix4x4d &val);
215 
216 // Convert decimal coordinates to degree/minute/second format and return as string
217 std::string DecimalToDegMinSec(float dec);
218 
219 // add a few things that MSVC is missing
220 #if defined(_MSC_VER) && (_MSC_VER < 1800)
221 
222 // round & roundf. taken from http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/auxiliary/util/u_math.h
223 static inline double round(double x)
224 {
225  return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5);
226 }
227 
228 static inline float roundf(float x)
229 {
230  return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
231 }
232 #endif /* _MSC_VER < 1800 */
233 
234 static inline Uint32 ceil_pow2(Uint32 v)
235 {
236  v--;
237  v |= v >> 1;
238  v |= v >> 2;
239  v |= v >> 4;
240  v |= v >> 8;
241  v |= v >> 16;
242  v++;
243  return v;
244 }
245 
246 // An adaptor for automagic reverse range-for iteration of containers
247 // One might be able to specialize this for raw arrays, but that's beyond the
248 // point of its use-case.
249 // One might also point out that this is surely more work to code than simply
250 // writing an explicit iterator loop, to which I say: bah humbug!
251 template <typename T>
253  using iterator = typename T::reverse_iterator;
254  using const_iterator = typename T::const_reverse_iterator;
255 
256  using value_type = typename std::remove_reference<T>::type;
257 
259  ref(ref) {}
260 
261  iterator begin() { return ref.rbegin(); }
262  const_iterator begin() const { return ref.crbegin(); }
263 
264  iterator end() { return ref.rend(); }
265  const_iterator end() const { return ref.crend(); }
266 
267 private:
268  value_type &ref;
269 };
270 
271 // Use this function for automatic template parameter deduction
272 template <typename T>
274 
275 void hexdump(const unsigned char *buf, int bufsz);
276 
277 #endif /* _UTILS_H */
double val
Definition: PrecalcPath.cpp:40
Sint64 v
Definition: fixed.h:239
void LogOld(Severity sv, std::string message)
Definition: Log.cpp:144
void LogFatalOld(std::string message)
Definition: Log.cpp:152
Definition: utils.h:252
reverse_container_t(value_type &ref)
Definition: utils.h:258
iterator end()
Definition: utils.h:264
typename T::reverse_iterator iterator
Definition: utils.h:253
const_iterator end() const
Definition: utils.h:265
typename std::remove_reference< T >::type value_type
Definition: utils.h:256
const_iterator begin() const
Definition: utils.h:262
iterator begin()
Definition: utils.h:261
typename T::const_reverse_iterator const_iterator
Definition: utils.h:254
float StrToFloat(const std::string &str)
Definition: utils.cpp:449
std::string format_date_only(double time)
Definition: utils.cpp:84
std::vector< std::string > SplitString(const std::string &source, const std::string &delim)
Definition: utils.cpp:191
bool ends_with(const std::string_view s, const std::string_view t)
Definition: utils.h:104
void Vector3fToStr(const vector3f &val, char *out, size_t size)
Definition: utils.cpp:275
void Vector3dToStr(const vector3d &val, char *out, size_t size)
Definition: utils.cpp:293
void Matrix4x4fToStr(const matrix4x4f &val, char *out, size_t size)
Definition: utils.cpp:359
void Matrix3x3dToStr(const matrix3x3d &val, char *out, size_t size)
Definition: utils.cpp:335
void StrToAuto(Sint32 *pVal, const std::string &str)
Definition: utils.cpp:486
void Output(const char *message, Args... args)
Definition: utils.h:41
void StrToVector3f(const char *str, vector3f &val)
Definition: utils.cpp:506
void Matrix4x4dToStr(const matrix4x4d &val, char *out, size_t size)
Definition: utils.cpp:385
bool starts_with(const std::string_view s, const std::string_view t)
Definition: utils.h:97
void Matrix3x3fToStr(const matrix3x3f &val, char *out, size_t size)
Definition: utils.cpp:311
bool ends_with_ci(const std::string_view s, const std::string_view t)
Definition: utils.h:124
Uint64 StrToUInt64(const std::string &str)
Definition: utils.cpp:442
reverse_container_t< T > reverse_container(T &ref)
Definition: utils.h:273
std::string format_money(double cents, bool showCents=true)
Definition: utils.cpp:18
std::string FloatToStr(float val)
Definition: utils.cpp:241
void DebugMsg(const char *message, Args... args)
Definition: utils.h:59
void StrToMatrix3x3f(const char *str, matrix3x3f &val)
Definition: utils.cpp:542
std::string string_join(std::vector< std::string > &v, std::string sep)
Definition: utils.cpp:95
bool starts_with_ci(const std::string_view s, const std::string_view t)
Definition: utils.h:112
void StrToMatrix4x4d(const char *str, matrix4x4d &val)
Definition: utils.cpp:602
void Warning(const char *message, Args... args)
Definition: utils.h:47
void hexdump(const unsigned char *buf, int bufsz)
Definition: utils.cpp:636
std::string format_date(double time)
Definition: utils.cpp:71
std::string format_duration(double seconds)
Definition: utils.cpp:108
void StrToMatrix4x4f(const char *str, matrix4x4f &val)
Definition: utils.cpp:582
std::string AutoToStr(Sint32 val)
Definition: utils.cpp:411
void StrToMatrix3x3d(const char *str, matrix3x3d &val)
Definition: utils.cpp:562
std::string format_distance(double dist, int precision=2)
Definition: utils.cpp:132
const char * pi_strcasestr(const char *haystack, const char *needle)
Definition: utils.cpp:160
double StrToDouble(const std::string &str)
Definition: utils.cpp:467
std::string DoubleToStr(double val)
Definition: utils.cpp:258
void Error(const char *message, Args... args)
Definition: utils.h:53
Sint64 StrToSInt64(const std::string &str)
Definition: utils.cpp:435
std::string DecimalToDegMinSec(float dec)
Definition: utils.cpp:626
void StrToVector3d(const char *str, vector3d &val)
Definition: utils.cpp:524