Files
OpenVulkano/openVulkanoCpp/Base/Utils.hpp
2025-01-21 15:14:14 +02:00

228 lines
5.5 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <vector>
#include <string>
#include <set>
#include <algorithm>
#include <array>
#include <bit>
#include <cassert>
#include <cinttypes>
#include <atomic>
#include "Data/Containers/Array.hpp"
namespace OpenVulkano
{
class Utils
{
static std::atomic_int uniqueTypeID;
public:
static void SetThreadName(const std::string& name);
static std::string GetThreadName();
static uint64_t GetThreadId();
static inline std::vector<const char*> toCString(const std::vector<std::string>& values)
{
std::vector<const char*> result;
result.reserve(values.size());
for (const auto& string : values) {
result.push_back(string.c_str());
}
return result;
}
static inline std::vector<const char*> toCString(const std::set<std::string>& values)
{
std::vector<const char*> result;
result.reserve(values.size());
for (const auto& string : values) {
result.push_back(string.c_str());
}
return result;
}
template<typename T, typename... N>
static auto MakeStdArray(N&&... args) -> std::array<T, sizeof...(args)>
{
return { std::forward<N>(args)... };
}
template<typename T, typename U>
static bool GetFlag(T var, U flag)
{
return var & flag;
}
template<typename T, typename U>
static void SetFlag(T& var, U flag)
{
var |= flag;
}
template<typename T, typename U>
static void ResetFlag(T& var, U flag)
{
var &= ~flag;
}
template <typename T>
static inline bool Contains(std::vector<T>& vec, const T& element)
{
return (std::find(vec.begin(), vec.end(), element) != vec.end());
}
template <typename T>
static inline void Remove(std::vector<T>& vec, const T& element)
{
vec.erase(std::remove(vec.begin(), vec.end(), element), vec.end());
}
template <typename Enumeration>
static inline auto EnumAsInt(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
static inline constexpr size_t Align(size_t size, size_t alignment)
{
return (size + alignment - 1) & ~(alignment - 1);
}
static inline constexpr size_t AlignPage(size_t size)
{
return Align(size, 4096); //TODO detect system page size instead of relying on hardcoded value
}
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
static inline constexpr bool IsPow2(T i)
{
return ((i - 1) & i) == 0;
}
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
static inline constexpr T Log2OfPow2(T n)
{
assert(n != 0);
assert(IsPow2(n));
T log = 0;
while(true)
{
n >>= 1;
if (n == 0)
{
break;
}
log++;
}
return log;
}
static constexpr int64_t OctToInt(std::string_view string)
{
int64_t result = 0;
for(int i = 0; i < static_cast<int>(string.length()); i++)
{
char c = string[i];
if (c == 0) break;
if (c == ' ') continue;
if (c < '0' || c > '7') return -1;
result = result * 8 + c - '0';
}
return result;
}
[[deprecated]]
static constexpr bool IsLittleEndian()
{
constexpr bool isLittleEndian = std::endian::native == std::endian::little;
return isLittleEndian;
}
static constexpr bool StartsWith(std::string_view str, std::string_view prefix)
{
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
}
static constexpr bool EndsWith(std::string_view str, std::string_view suffix)
{
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
}
static void ToLower(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), [](char c) { std::tolower(c); });
}
static void ToLower(const std::string& str, char* dest)
{
std::transform(str.begin(), str.end(), dest, [](char c) { std::tolower(c); });
}
static std::string ToLower(const std::string& str)
{
std::string dest;
dest.reserve(str.size());
std::transform(str.begin(), str.end(), dest.begin(), [](char c) { std::tolower(c); });
return dest;
}
static std::pair<std::string, std::string> SplitAtLastOccurrence(const std::string& str, char splitAt)
{
size_t pos = str.rfind(splitAt);
if (pos == std::string::npos) return {str, ""};
else return {str.substr(0, pos), str.substr(pos + 1)};
}
static std::vector<std::string> Split(const std::string_view& str, char separator)
{
std::vector<std::string> subs;
size_t startPos = 0, pos;
while ((pos = str.find(separator, startPos)) != std::string::npos)
{
if (pos != startPos)
{
subs.emplace_back(str.substr(startPos, pos - startPos));
}
startPos = pos + 1;
}
if (startPos < str.size())
{
subs.emplace_back(str.substr(startPos));
}
return subs;
}
template<typename T>
static Array<char> ReadFile(const T& filePath, bool emptyOnMissing = false,
bool nullTerminateString = false);
template<size_t N>
static Array<char> ReadFile(const char (&filePath)[N], bool emptyOnMissing = false,
bool nullTerminateString = false)
{
return ReadFile(std::string(filePath), emptyOnMissing, nullTerminateString);
}
template<class T>
static int GetUniqueTypeId()
{
static const int id = uniqueTypeID++;
return id;
}
static std::string DemangleTypeName(const char* name);
};
}