Files
FlaxEngine/Source/Engine/Core/Utilities.h
2023-10-20 11:22:22 +02:00

98 lines
3.1 KiB
C++

// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Types/BaseTypes.h"
#include "Types/String.h"
#include "Types/Span.h"
#if _MSC_VER && PLATFORM_SIMD_SSE4_2
#include <intrin.h>
#endif
namespace Utilities
{
struct Private
{
static FLAXENGINE_API Span<const Char*> BytesSizes;
static FLAXENGINE_API Span<const Char*> HertzSizes;
};
// Round floating point value up to 1 decimal place
template<typename T>
FORCE_INLINE T RoundTo1DecimalPlace(T value)
{
return (T)round((double)value * 10) / (T)10;
}
// Round floating point value up to 2 decimal places
template<typename T>
FORCE_INLINE T RoundTo2DecimalPlaces(T value)
{
return (T)round((double)value * 100.0) / (T)100;
}
// Round floating point value up to 3 decimal places
template<typename T>
FORCE_INLINE T RoundTo3DecimalPlaces(T value)
{
return (T)round((double)value * 1000.0) / (T)1000;
}
// Converts units to the best fitting human-readable denominator
// @param units Units count
// @param divider Amount of units required for the next size
// @param sizes Array with human-readable sizes to convert from
// @return The best fitting string of the units
template<typename T>
String UnitsToText(T units, int32 divider, const Span<const Char*> sizes)
{
if (sizes.Length() == 0)
return String::Format(TEXT("{0}"), units);
int32 i = 0;
double dblSUnits = static_cast<double>(units);
for (; static_cast<uint64>(units / static_cast<double>(divider)) > 0; i++, units /= divider)
dblSUnits = (double)units / (double)divider;
if (i >= sizes.Length())
i = 0;
String text = String::Format(TEXT("{}"), RoundTo2DecimalPlaces(dblSUnits));
const int32 dot = text.FindLast('.');
if (dot != -1)
text = text.Left(dot + 3);
return String::Format(TEXT("{0} {1}"), text, sizes[i]);
}
// Converts size of the file (in bytes) to the best fitting string
// @param bytes Size of the file in bytes
// @return The best fitting string of the file size
template<typename T>
String BytesToText(T bytes)
{
return UnitsToText(bytes, 1024, Private::BytesSizes);
}
// Converts hertz to the best fitting string
// @param hertz Hertz for convertion
// @return The best fitting string
template<typename T>
String HertzToText(T hertz)
{
return UnitsToText(hertz, 1000, Private::HertzSizes);
}
// Returns the amount of set bits in 32-bit integer.
inline int32 CountBits(uint32 x)
{
// [Reference: https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer]
#ifdef __GNUC_
return __builtin_popcount(x);
#elif _MSC_VER && PLATFORM_SIMD_SSE4_2
return __popcnt(x);
#else
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
return (x * 0x01010101) >> 24;
#endif
}
}