Trax3 3.1.0
trax track library
Loading...
Searching...
No Matches
Helpers.h
1// trax track library
2// AD 2013
3//
4// "maloca bocada fubanga"
5//
6// Sepultura
7//
8//
9// Copyright (c) 2025 Trend Redaktions- und Verlagsgesellschaft mbH
10// Copyright (c) 2019 Marc-Michael Horstmann
11//
12// Permission is hereby granted to any person obtaining a copy of this software
13// and associated source code (the "Software"), to use, view, and study the
14// Software for personal or internal business purposes, subject to the following
15// conditions:
16//
17// 1. Redistribution, modification, sublicensing, or commercial use of the
18// Software is NOT permitted without prior written consent from the copyright
19// holder.
20//
21// 2. The Software is provided "AS IS", without warranty of any kind, express
22// or implied.
23//
24// 3. All copies of the Software must retain this license notice.
25//
26// For further information, please contact: horstmann.marc@trendverlag.de
27
28
29
30#pragma once
31
32#include "NarrowCast.h"
33
34#include <set>
35#include <string>
36#include <codecvt>
37#include <locale>
38#include <vector>
39#include <cmath>
40#include <cassert>
41
43namespace common{
44
50 template<typename T> inline constexpr T Square( T val ) noexcept{
51 return val * val;
52 }
53
56 template<typename T> inline constexpr T Cube( T val ) noexcept{
57 return val * val * val;
58 }
59
61 template<int Y, typename T> inline constexpr T pow( T val ) noexcept{
62 return static_cast<T>(std::pow(val,Y)); //? why is this acting as constexpr???
63 }
64
66 template<typename T> inline constexpr bool Equals( T a, T b, T epsilon ) noexcept{
67 using std::abs; // prevent using int version when inadequate.
68 return abs( a - b ) <= epsilon;
69 }
70
72 template <typename T> inline constexpr auto Sign(T val) noexcept -> decltype(T{}/T{}){
73 return static_cast<decltype(T{}/T{})>((T{0} < val) - (val < T{0}));
74 }
75
77 inline constexpr int Factorial( int n ) {
78 assert( n >= 0 );
79 return (n == 1 || n == 0) ? 1 : Factorial(n - 1) * n;
80 }
81
87 template<typename T1,typename T2> inline
88 T1 Clip( T1& val, const T2& min, const T2& max ) noexcept{
89 if( min > max )
90 return Clip( val, max, min );
91
92 if( val < min )
93 val = static_cast<T1>(min);
94 else if( val > max )
95 val = static_cast<T1>(max);
96
97 return val;
98 }
99
100
104 template<class T>
105 constexpr const T& Clamp( const T& v, const T& lo, const T& hi ) noexcept{
106 if( v < lo ) return lo;
107 if( hi < v ) return hi;
108 return v;
109 }
110
117 template<typename T1,typename T2> inline
118 T1 Wrap( const T1& val, const T2& min, const T2& max ) noexcept{
119 if( max == min )
120 return val;
121
122 if( min > max )
123 return Wrap( val, max, min );
124
125 T1 retVal = val;
126 if( val >= max )
127 retVal = static_cast<T1>(std::fmod(min + (val - max), max - min));
128 else if( val < min )
129 retVal = static_cast<T1>(std::fmod(max - (min - val), max - min ));
130
131 return retVal;
132 }
133
139 template<class T> inline
140 T Round( T value, int toDigit ) noexcept
141 {
142 const float pow10{ std::pow( 10.f, static_cast<float>(toDigit) ) };
143 return round( value * pow10 ) / pow10;
144 }
145
146
150 template<typename Valtype> inline
151 Valtype DealDenormalizedNumbers( Valtype val ){
152 if( abs( val ) < (std::numeric_limits<Valtype>::min)() )
153 return Valtype{ 0 };
154 return val;
155 }
156
161 template<typename Valtype>
162 inline constexpr Valtype FirstPearl( int cntPearls, Valtype distPearls ) noexcept{
163 return ( 1 - cntPearls ) * 0.5f * distPearls;
164 }
165
166 inline char to_uppercase( unsigned char c)
167 {
168 return narrow_cast<char>(std::toupper(c));
169 }
170
171 inline char to_lowercase( unsigned char c)
172 {
173 return narrow_cast<char>(std::tolower(c));
174 }
175
177 inline std::string quoted( const std::string& str ){
178 std::string quotedStr = "\"";
179 quotedStr += str;
180 quotedStr += "\"";
181 return quotedStr;
182 }
183
184
187 inline std::string StripApostrophes( const std::string& str ){
188 std::string _str(str);
189 if(_str.size() >= 2 ){
190 if( (*_str.cbegin() == '\"' && *_str.crbegin() == '\"') ||
191 (*_str.cbegin() == '\'' && *_str.crbegin() == '\'') ){
192 _str.erase( _str.begin() );
193 _str.erase( _str.end()-1 );
194 }
195 }
196
197 return _str;
198 }
199
201 inline std::string StripReservedCharacters( const std::string& str ){
202 std::string retval;
203 for( std::size_t i = 0; i < str.size(); ++i ){
204 const char& c = str.at(i);
205 if( c != '/' &&
206 c != '\\' &&
207 c != '?' &&
208 c != '%' &&
209 c != '*' &&
210 c != ':' &&
211 c != '|' &&
212 c != '"' &&
213 c != '\'' &&
214 c != '<' &&
215 c != '>' &&
216 c != '.' )
217 retval += c;
218 }
219 return retval;
220 }
221
224 inline std::string Indent( int indent ){
225 //return std::string{ static_cast<std::size_t>(indent), ' ' };
226 std::string retval;
227 for( int i = indent; i != 0; --i )
228 retval += " ";
229
230 return retval;
231 }
232
233 //inline int Determinant_sign(const boost::numeric::ublas::permutation_matrix<std::size_t>& pm)
234 //{
235 // int pm_sign=1;
236 // std::size_t size = pm.size();
237 // for (std::size_t i = 0; i < size; ++i)
238 // if (i != pm(i))
239 // pm_sign *= -1; // swap_rows would swap a pair of rows here, so we change sign
240 // return pm_sign;
241 //}
242
243 //template<typename Valtype> inline
244 //Valtype Determinant( boost::numeric::ublas::matrix<Valtype>& m ) {
245 // using namespace boost::numeric::ublas;
246
247 // permutation_matrix<std::size_t> pm(m.size1());
248 // Valtype det = 1;
249 // if( lu_factorize(m,pm) ) {
250 // det = 0;
251 // } else {
252 // for(std::size_t i = 0; i < m.size1(); i++)
253 // det *= m(i,i); // multiply by elements on diagonal
254 // det = det * Determinant_sign( pm );
255 // }
256 // return det;
257 //}
258
259
263 template<typename Valtype> inline
264 Valtype AttenuateValue( Valtype value, Valtype dattenuation ) noexcept
265 {
266 const Valtype dvalue = -dattenuation * value;
267 if( std::abs(value) < std::abs(dvalue) )
268 return 0.0f;
269
270 return value + dvalue;
271 }
272
273
275 template<typename T> class UniqueKey{
276 std::set<T> m_OccupiedKeys;
277 public:
278
280 bool Occupy( T key ){
281 return m_OccupiedKeys.insert( key ).second;
282 }
283
284
286 bool Free( T key ){
287 return m_OccupiedKeys.erase( key ) ? true : false;
288 }
289
290
292 void FreeAll() noexcept{
293 m_OccupiedKeys.clear();
294 }
295
296
299 T x = 1;
300 for( auto csiter = m_OccupiedKeys.begin();
301 csiter != m_OccupiedKeys.end(); ++x, ++csiter )
302 {
303 if( x == *csiter )
304 continue;
305
306 m_OccupiedKeys.insert( x );
307 return x;
308 }
309
310 m_OccupiedKeys.insert( x );
311 return x;
312 }
313
314
316 bool IsFree( T key ) const{
317 return (m_OccupiedKeys.find( key ) == m_OccupiedKeys.end());
318 }
319 };
320
329 template<typename Valtype>
330 constexpr Valtype Collision( Valtype m1, Valtype m2, Valtype v1, Valtype v2, Valtype k ){
331 return m1*m2/ (m1+m2) * (v2-v1) * (1+k);
332 }
333
334 inline void TranslateEscapeCharacters( std::string& string ){
335 for( std::size_t pos = string.find( "[e]" ); pos != string.npos; pos = string.find( "[e]", pos ) )
336 string.replace( pos, 3, "\n" );
337 }
338
340 inline std::string utf8_to_string( const std::string& utf8str, const std::locale& loc = std::locale("") )
341 // @implementation: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html
342 // it say's "this library component should be retired to Annex D, along side , until a suitable replacement is standardized"
343 // i.e. D.18.1. TODO: substitute implementation with the replacement when available. Until then, use deprecated feature.
344 {
345 // UTF-8 to wstring
346#if defined(_MSC_VER)
347# pragma warning(push)
348# pragma warning(disable: 4996) // deprecated stl feature
349#endif
350 std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;
351 std::wstring wstr = wconv.from_bytes(utf8str.c_str());
352#if defined(_MSC_VER)
353# pragma warning(pop)
354#endif
355 // wstring to string
356 std::vector<char> buf(wstr.size());
357 std::use_facet<std::ctype<wchar_t>>(loc).narrow(wstr.data(), wstr.data() + wstr.size(), '?', buf.data());
358 return std::string(buf.data(), buf.size());
359 }
360
362 class FlagBlocker{
363 bool& m_Flag;
364 public:
368 FlagBlocker( bool& blocker ) noexcept
369 : m_Flag{blocker}
370 {
371 m_Flag = !m_Flag;
372 }
373 FlagBlocker() = delete;
374 FlagBlocker( const FlagBlocker& ) = delete;
375 FlagBlocker( FlagBlocker&& ) = delete;
377
378 ~FlagBlocker() noexcept{
379 m_Flag = !m_Flag;
380 }
381
382 FlagBlocker& operator=( const FlagBlocker& ) = delete;
383 FlagBlocker& operator=( FlagBlocker&& ) = delete;
384 };
385
386
388 template<typename ValueType>
389 class Resetter{
390 ValueType& m_Variable;
391 ValueType m_OriginalValue;
392 bool m_bDismiss = false;
393 public:
394 Resetter() = delete;
395 Resetter( const Resetter& ) = delete;
396 Resetter( Resetter&& ) = delete;
397 Resetter( ValueType& variable, ValueType toValue ) noexcept
398 : m_Variable { variable },
399 m_OriginalValue { variable }
400 {
401 m_Variable = toValue;
402 }
403
404 ~Resetter(){
405 if( !m_bDismiss )
406 m_Variable = m_OriginalValue;
407 }
408
409 Resetter& operator=( const Resetter& ) = delete;
410 Resetter& operator=( Resetter&& ) = delete;
411
412
413 void Dismiss(){
414 m_bDismiss = true;
415 }
416 };
417
418
420 template <class ContainerAdapter>
421 class ContainerAdapterExtension : public ContainerAdapter {
422 public:
423 typedef typename ContainerAdapter::container_type container_type;
424
425 const container_type& get_container() const noexcept { return this->c; }
426 };
427}
stl container adapter extension for accessing the underlying container.
Definition Helpers.h:421
Set of unique keys.
Definition Helpers.h:275
bool IsFree(T key) const
Is the key already occupied?
Definition Helpers.h:316
bool Occupy(T key)
Reserve a key.
Definition Helpers.h:280
T GetFree()
Get a free key. The key will be occupied after the call.
Definition Helpers.h:298
bool Free(T key)
Make a key available in the future.
Definition Helpers.h:286
void FreeAll() noexcept
Release all the keys, making them available.
Definition Helpers.h:292
Namespace of common utility classes and methods.
Definition Helpers.h:43
constexpr Valtype Collision(Valtype m1, Valtype m2, Valtype v1, Valtype v2, Valtype k)
Calculates the impulse change of body 1 in a collision event.
Definition Helpers.h:330
constexpr T Cube(T val) noexcept
Definition Helpers.h:56
T1 Wrap(const T1 &val, const T2 &min, const T2 &max) noexcept
Wraps a val to a specified range as if max would be actually min.
Definition Helpers.h:118
constexpr T pow(T val) noexcept
power function with templated integer exponent.
Definition Helpers.h:61
constexpr T Square(T val) noexcept
This is usefull because it saves a temp.
Definition Helpers.h:50
std::string StripReservedCharacters(const std::string &str)
Removes characters that might not be allowed for file names.
Definition Helpers.h:201
constexpr auto Sign(T val) noexcept -> decltype(T{}/T{})
Definition Helpers.h:72
Valtype DealDenormalizedNumbers(Valtype val)
Make too small numbers zero.
Definition Helpers.h:151
constexpr int Factorial(int n)
Definition Helpers.h:77
T Round(T value, int toDigit) noexcept
Rounding of floating point number to a certain digit aftzer the point.
Definition Helpers.h:140
constexpr const T & Clamp(const T &v, const T &lo, const T &hi) noexcept
Clips a val to a specified range.
Definition Helpers.h:105
std::string StripApostrophes(const std::string &str)
Removes the outmost apostrophes (''' and '"') from a string. Does nothing if the string isn't properl...
Definition Helpers.h:187
constexpr bool Equals(T a, T b, T epsilon) noexcept
Tests equality in the sense |a-b| < epsilon.
Definition Helpers.h:66
T1 Clip(T1 &val, const T2 &min, const T2 &max) noexcept
Clips a val to a specified range.
Definition Helpers.h:88
std::string quoted(const std::string &str)
Construct a quoted string.
Definition Helpers.h:177
Target narrow_cast(Source v)
Safe cast for casting numeric values.
Definition NarrowCast.h:60
constexpr Valtype FirstPearl(int cntPearls, Valtype distPearls) noexcept
Center an equidistant row of elements (pearls).
Definition Helpers.h:162
Valtype AttenuateValue(Valtype value, Valtype dattenuation) noexcept
Attenuates value by the factor dattenuation.
Definition Helpers.h:264
std::string utf8_to_string(const std::string &utf8str, const std::locale &loc=std::locale(""))
convert multibyte character string (UTF-8) to ANSI string.
Definition Helpers.h:340
std::string Indent(int indent)
Needed since for unknown reason, the straightforward implementation std::string{ indent,...
Definition Helpers.h:224