CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Utility.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
15
16#include <algorithm>
17#include <bit>
18#include <cctype>
19#include <cmath>
20#include <concepts>
21#include <functional>
22#include <iomanip>
23#include <iterator>
24#include <memory>
25#include <sstream>
26#include <type_traits>
27
28namespace CeresEngine {
29
30 // Removes all entries from the specified container which are equal to the specified type.
31 template<typename TCollection, typename TValue> void eraseAll(TCollection& collection, const TValue& value) {
32 collection.erase(std::remove(std::begin(collection), std::end(collection), value), std::end(collection));
33 }
34
35 // Removes all entries from the specified container for which the specified predicate is true.
36 template<typename TCollection, typename TPredicate> void eraseAllIf(TCollection& collection, TPredicate pred) {
37 collection.erase(std::remove_if(std::begin(collection), std::end(collection), pred), std::end(collection));
38 }
39
40 // Moves all entries from the source into the destination.
41 template<typename TCollectionSrc, typename TCollectionDest> void moveAll(TCollectionSrc& src, TCollectionDest& dst) {
42 std::move(std::begin(src), std::end(src), std::back_inserter(dst));
43 src.clear();
44 }
45
46 // Moves all entries from the source into the destination for which the specified predicate is true.
47 template<typename TCollectionSrc, typename TCollectionDest, typename TPredicate>
48 void moveAllIf(TCollectionSrc& src, TCollectionDest& dst, TPredicate pred) {
49 for(auto it = src.begin(); it != src.end();) {
50 if(pred(*it)) {
51 dst.push_back(*it);
52 it = src.erase(it);
53 } else {
54 ++it;
55 }
56 }
57 }
58
59 // Replaces all occurances of 'from' in the string 's' by 'to'.
60 template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
61 void replace(std::basic_string<CharT, Traits, Allocator>& s, const std::basic_string<CharT, Traits, Allocator>& from,
62 const std::basic_string<CharT, Traits, Allocator>& to) {
63 using T = std::basic_string<CharT, Traits, Allocator>;
64 for(typename T::size_type pos = 0; (pos = s.find(from, pos)) != T::npos; pos += to.size()) {
65 s.replace(pos, from.size(), to);
66 }
67 }
68
69 // Replaces all occurances of 'from' in the string 's' by 'to'.
70 template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
71 void replace(std::basic_string<CharT, Traits, Allocator>& s, const char* from, const char* to) {
72 Replace(s, std::basic_string<CharT, Traits, Allocator>(from), std::basic_string<CharT, Traits, Allocator>(to));
73 }
74
75 // Replaces all occurances of 'from' in the string 's' by 'to'.
76 template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
77 void replace(std::basic_string<CharT, Traits, Allocator>& s, const std::basic_string<CharT, Traits, Allocator>& from, const char* to) {
78 Replace(s, from, std::basic_string<CharT, Traits, Allocator>(to));
79 }
80
81 // Replaces all occurances of 'from' in the string 's' by 'to'.
82 template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
83 void replace(std::basic_string<CharT, Traits, Allocator>& s, const char* from, const std::basic_string<CharT, Traits, Allocator>& to) {
84 Replace(s, std::basic_string<CharT, Traits, Allocator>(from), to);
85 }
86
87 // Parses a number from the specified string with std::stoi, std::stoll, std::stof, or std::stod
88 template<typename T> inline T fromStringOrDefault(const StringView& s) {
89 throw std::runtime_error("default template of fromStringOrDefault<T> not implemented");
90 }
91
92 // Returns true if the specified string contains a hexadecimal number.
93 inline bool isHexLiteral(const StringView& s) { return (s.size() >= 3 && s[0] == '0' && ::toupper(s[1]) == 'X'); }
94
95 template<> inline int fromStringOrDefault<int>(const StringView& s) {
96 try {
97 return std::stoi(std::string(s), nullptr, (isHexLiteral(s) ? 16 : 10));
98 } catch(const std::exception&) {
99 return 0;
100 }
101 }
102
103 template<> inline long long fromStringOrDefault<long long>(const StringView& s) {
104 try {
105 return std::stoll(std::string(s), nullptr, (isHexLiteral(s) ? 16 : 10));
106 } catch(const std::exception&) {
107 return 0ll;
108 }
109 }
110
111 template<> inline unsigned long fromStringOrDefault<unsigned long>(const StringView& s) {
112 try {
113 return std::stoul(std::string(s), nullptr, (isHexLiteral(s) ? 16 : 10));
114 } catch(const std::exception&) {
115 return 0ul;
116 }
117 }
118
119 template<> inline float fromStringOrDefault<float>(const StringView& s) {
120 try {
121 return std::stof(std::string(s));
122 } catch(const std::exception&) {
123 return 0.0f;
124 }
125 }
126
127 template<> inline double fromStringOrDefault<double>(const StringView& s) {
128 try {
129 return std::stod(std::string(s));
130 } catch(const std::exception&) {
131 return 0.0;
132 }
133 }
134
135 // Transforms the specified string to upper case.
136 template<typename T> void toUpper(T& s) { std::transform(std::begin(s), std::end(s), std::begin(s), ::toupper); }
137
141 template<typename T, typename Allocator>
143 const auto nDst = dst.size();
144 const auto nSrc = src.size();
145
148
149 for(; i < nDst; ++i) {
150 if(i < nSrc) {
151 if(dst[i] != keepDst && src[i] != ignoreSrc) {
152 dst[i] = src[i];
153 }
154 } else {
155 return;
156 }
157 }
158
160 if(i < nSrc) {
161 dst.append(src.substr(i));
162 }
163 }
164
165 // Returns a hexa-decimal string of the specified integral value.
166 template<typename T> String toHexString(const T& i, const String& prefix = "0x") {
168 s << prefix << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << i;
169 return s.str();
170 }
171
172 // Returns the number of digits of the specified integral type.
173 template<typename T> int numDigits(T n) {
174 static_assert(std::is_integral<T>::value, "NumDigits template only allows integral types");
175
176 int digits = (n < 0 ? 1 : 0);
177
178 while(n != 0) {
179 n /= 10;
180 ++digits;
181 }
182
183 return digits;
184 }
185
186 // Equivalent to C++14's 'std::exchange(ptr, nullptr)'.
187 template<typename T> SPtr<T> exchangeWithNull(SPtr<T>& ptr) {
188 auto result = ptr;
189 ptr.reset();
190 return result;
191 }
192
194 enum class Endian {
195 Big = UInt8(std::endian::big),
196 Little = UInt8(std::endian::little),
197 Native = UInt8(std::endian::native),
198 };
199
200 namespace impl {
201 template<Endian, typename T> struct ByteSwapper {
203 if constexpr(sizeof(T) == 1) {
204 return u;
205 } else
206#if CE_COMPILER_CLANG
207 if constexpr(std::is_same_v<T, UInt16> || std::is_same_v<T, Int16>) {
208 return __builtin_bswap16(u);
209 } else if constexpr(std::is_same_v<T, UInt32> || std::is_same_v<T, Int32>) {
210 return __builtin_bswap32(u);
211 } else if constexpr(std::is_same_v<T, UInt64> || std::is_same_v<T, Int64>) {
212 return __builtin_bswap64(u);
213 } else
214#elif CE_COMPILER_MSVC
215 if constexpr(std::is_same_v<T, UInt16> || std::is_same_v<T, Int16>) {
216 return _byteswap_ushort(u);
217 } else if constexpr(std::is_same_v<T, UInt32> || std::is_same_v<T, Int32>) {
218 return _byteswap_ulong(u);
219 } else if constexpr(std::is_same_v<T, UInt64> || std::is_same_v<T, Int64>) {
220 return _byteswap_uint64(u);
221 } else
222#endif
223 {
224 static_assert(sizeof(Byte) == 1);
225
226 union {
227 T u;
228 Byte u8[sizeof(T)];
229 } source, destination;
230
231 source.u = u;
232 for(size_t k = 0; k < sizeof(T); k++) {
233 destination.u8[k] = source.u8[sizeof(T) - k - 1];
234 }
235
236 return destination.u;
237 }
238 }
239 };
240
241 template<typename T> struct ByteSwapper<Endian::Native, T> {
242 T operator()(T u) { return u; }
243 };
244 } // namespace impl
245
250 template<Endian E, typename T>
251 requires(std::is_trivially_copyable_v<T>) [[nodiscard]] T byteswap(T u) { return impl::ByteSwapper<E, T>{}(u); }
252
253} // namespace CeresEngine
Basic string that uses framework's memory allocators.
Definition String.hpp:60
Definition Application.hpp:19
int numDigits(T n)
Definition Utility.hpp:173
Byte
Definition DataTypes.hpp:40
bool isHexLiteral(const StringView &s)
Definition Utility.hpp:93
std::shared_ptr< T > SPtr
SPtr is a smart pointer that retains shared ownership of an object through a pointer.
Definition SmartPtr.hpp:37
void mergeString(BasicString< T, Allocator > &dst, const BasicString< T, Allocator > &src, const T &keepDst, const T &ignoreSrc)
Merges the source string 'src' into the destination string 'dst', keeps the destination characters sp...
Definition Utility.hpp:142
BasicStringStream< char > StringStream
Wide string stream used for primarily for constructing narrow strings.
Definition StringStream.hpp:32
unsigned long fromStringOrDefault< unsigned long >(const StringView &s)
Definition Utility.hpp:111
void eraseAllIf(TCollection &collection, TPredicate pred)
Definition Utility.hpp:36
float fromStringOrDefault< float >(const StringView &s)
Definition Utility.hpp:119
SPtr< T > exchangeWithNull(SPtr< T > &ptr)
Definition Utility.hpp:187
T fromStringOrDefault(const StringView &s)
Definition Utility.hpp:88
void moveAll(TCollectionSrc &src, TCollectionDest &dst)
Definition Utility.hpp:41
Endian
A enumeration for possible endinesses.
Definition Utility.hpp:194
void moveAllIf(TCollectionSrc &src, TCollectionDest &dst, TPredicate pred)
Definition Utility.hpp:48
@ Replace
Set the stencil data to the reference value.
double fromStringOrDefault< double >(const StringView &s)
Definition Utility.hpp:127
std::uint8_t UInt8
Definition DataTypes.hpp:17
void toUpper(T &s)
Definition Utility.hpp:136
void eraseAll(TCollection &collection, const TValue &value)
Definition Utility.hpp:31
T byteswap(T u)
Swaps the byte to/from the native byte-order to the target E byte-order.
Definition Utility.hpp:251
String toHexString(const T &i, const String &prefix="0x")
Definition Utility.hpp:166
long long fromStringOrDefault< long long >(const StringView &s)
Definition Utility.hpp:103
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
int fromStringOrDefault< int >(const StringView &s)
Definition Utility.hpp:95
void replace(std::basic_string< CharT, Traits, Allocator > &s, const std::basic_string< CharT, Traits, Allocator > &from, const std::basic_string< CharT, Traits, Allocator > &to)
Definition Utility.hpp:61
T operator()(T u)
Definition Utility.hpp:242
Definition Utility.hpp:201
T operator()(T u)
Definition Utility.hpp:202