|
|
@@ -8,79 +8,77 @@
|
|
|
#include <AnKi/Util/Common.h>
|
|
|
#include <cstdint>
|
|
|
#include <cstddef>
|
|
|
+#include <cstring>
|
|
|
#include <limits>
|
|
|
#include <type_traits>
|
|
|
|
|
|
namespace anki {
|
|
|
|
|
|
-/// @addtogroup util_other
|
|
|
-/// @{
|
|
|
-
|
|
|
-using I8 = int8_t; ///< Integer 8bit
|
|
|
+using I8 = int8_t; // Integer 8bit
|
|
|
constexpr I8 kMaxI8 = std::numeric_limits<I8>::max();
|
|
|
constexpr I8 kMinI8 = std::numeric_limits<I8>::min();
|
|
|
|
|
|
-using I16 = int16_t; ///< Integer 16bit
|
|
|
+using I16 = int16_t; // Integer 16bit
|
|
|
constexpr I16 kMaxI16 = std::numeric_limits<I16>::max();
|
|
|
constexpr I16 kMinI16 = std::numeric_limits<I16>::min();
|
|
|
|
|
|
-using I32 = int32_t; ///< Integer 32bit
|
|
|
+using I32 = int32_t; // Integer 32bit
|
|
|
constexpr I32 kMaxI32 = std::numeric_limits<I32>::max();
|
|
|
constexpr I32 kMinI32 = std::numeric_limits<I32>::min();
|
|
|
|
|
|
-using I64 = int64_t; ///< Integer 64bit
|
|
|
+using I64 = int64_t; // Integer 64bit
|
|
|
constexpr I64 kMaxI64 = std::numeric_limits<I64>::max();
|
|
|
constexpr I64 kMinI64 = std::numeric_limits<I64>::min();
|
|
|
|
|
|
-using I = int_fast32_t; ///< Fast signed integer at least 32bit
|
|
|
+using I = int_fast32_t; // Fast signed integer at least 32bit
|
|
|
constexpr I kMaxI = std::numeric_limits<I>::max();
|
|
|
constexpr I kMinI = std::numeric_limits<I>::min();
|
|
|
|
|
|
-using U8 = uint8_t; ///< Unsigned integer 8bit
|
|
|
+using U8 = uint8_t; // Unsigned integer 8bit
|
|
|
constexpr U8 kMaxU8 = std::numeric_limits<U8>::max();
|
|
|
constexpr U8 kMinU8 = std::numeric_limits<U8>::min();
|
|
|
|
|
|
-using U16 = uint16_t; ///< Unsigned integer 16bit
|
|
|
+using U16 = uint16_t; // Unsigned integer 16bit
|
|
|
constexpr U16 kMaxU16 = std::numeric_limits<U16>::max();
|
|
|
constexpr U16 kMinU16 = std::numeric_limits<U16>::min();
|
|
|
|
|
|
-using U32 = uint32_t; ///< Unsigned integer 32bit
|
|
|
+using U32 = uint32_t; // Unsigned integer 32bit
|
|
|
constexpr U32 kMaxU32 = std::numeric_limits<U32>::max();
|
|
|
constexpr U32 kMinU32 = std::numeric_limits<U32>::min();
|
|
|
|
|
|
-using U64 = uint64_t; ///< Unsigned integer 64bit
|
|
|
+using U64 = uint64_t; // Unsigned integer 64bit
|
|
|
constexpr U64 kMaxU64 = std::numeric_limits<U64>::max();
|
|
|
constexpr U64 kMinU64 = std::numeric_limits<U64>::min();
|
|
|
|
|
|
-using U = uint_fast32_t; ///< Fast unsigned integer at least 32bit
|
|
|
+using U = uint_fast32_t; // Fast unsigned integer at least 32bit
|
|
|
constexpr U kMaxU = std::numeric_limits<U>::max();
|
|
|
constexpr U kMinU = std::numeric_limits<U>::min();
|
|
|
|
|
|
-using PtrSize = size_t; ///< Like size_t
|
|
|
+using PtrSize = size_t; // Like size_t
|
|
|
constexpr PtrSize kMaxPtrSize = std::numeric_limits<PtrSize>::max();
|
|
|
constexpr PtrSize kMinPtrSize = std::numeric_limits<PtrSize>::min();
|
|
|
static_assert(sizeof(PtrSize) == sizeof(void*), "Wrong size for size_t");
|
|
|
|
|
|
-using F32 = float; ///< Floating point 32bit
|
|
|
+using F32 = float; // Floating point 32bit
|
|
|
constexpr F32 kMaxF32 = std::numeric_limits<F32>::max();
|
|
|
constexpr F32 kMinF32 = -std::numeric_limits<F32>::max();
|
|
|
|
|
|
-using F64 = double; ///< Floating point 64bit
|
|
|
+using F64 = double; // Floating point 64bit
|
|
|
constexpr F64 kMaxF64 = std::numeric_limits<F64>::max();
|
|
|
constexpr F64 kMinF64 = -std::numeric_limits<F64>::max();
|
|
|
|
|
|
-using Bool = bool; ///< 1 byte boolean type. The same as C++'s bool.
|
|
|
+using Bool = bool; // 1 byte boolean type. The same as C++'s bool.
|
|
|
static_assert(sizeof(bool) == 1, "Wrong size for bool");
|
|
|
|
|
|
using Bool32 = I32;
|
|
|
using Char = char;
|
|
|
using WChar = wchar_t;
|
|
|
|
|
|
-using Second = F64; ///< The base time unit is second.
|
|
|
+using Second = F64; // The base time unit is second.
|
|
|
constexpr Second kMaxSecond = kMaxF64;
|
|
|
constexpr Second kMinSecond = kMinF64;
|
|
|
|
|
|
-using Timestamp = U64; ///< Timestamp type.
|
|
|
+using Timestamp = U64; // Timestamp type.
|
|
|
constexpr Timestamp kMaxTimestamp = kMaxU64;
|
|
|
|
|
|
// Numeric limits
|
|
|
@@ -115,68 +113,60 @@ ANKI_DO_LIMIT(F64, kMinF64, kMaxF64)
|
|
|
|
|
|
#undef ANKI_DO_LIMIT
|
|
|
|
|
|
-/// Representation of error and a wrapper on top of error codes.
|
|
|
+// Representation of error and a wrapper on top of error codes.
|
|
|
class [[nodiscard]] Error
|
|
|
{
|
|
|
public:
|
|
|
- /// @name Error codes
|
|
|
- /// @{
|
|
|
+ // Error codes
|
|
|
static constexpr I32 kNone = 0;
|
|
|
static constexpr I32 kOutOfMemory = 1;
|
|
|
- static constexpr I32 kFunctionFailed = 2; ///< External operation failed
|
|
|
+ static constexpr I32 kFunctionFailed = 2; // External operation failed
|
|
|
static constexpr I32 kUserData = 3;
|
|
|
|
|
|
// File errors
|
|
|
static constexpr I32 kFileNotFound = 4;
|
|
|
- static constexpr I32 kFileAccess = 5; ///< Read/write access error
|
|
|
+ static constexpr I32 kFileAccess = 5; // Read/write access error
|
|
|
|
|
|
static constexpr I32 kUnknown = 6;
|
|
|
- /// @}
|
|
|
|
|
|
- /// Construct using an error code.
|
|
|
+ // Construct using an error code.
|
|
|
Error(I32 code)
|
|
|
: m_code(code)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- /// Copy.
|
|
|
Error(const Error& b)
|
|
|
: m_code(b.m_code)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- /// Copy.
|
|
|
Error& operator=(const Error& b)
|
|
|
{
|
|
|
m_code = b.m_code;
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- /// Compare.
|
|
|
Bool operator==(const Error& b) const
|
|
|
{
|
|
|
return m_code == b.m_code;
|
|
|
}
|
|
|
|
|
|
- /// Compare.
|
|
|
Bool operator==(I32 code) const
|
|
|
{
|
|
|
return m_code == code;
|
|
|
}
|
|
|
|
|
|
- /// Compare.
|
|
|
Bool operator!=(const Error& b) const
|
|
|
{
|
|
|
return m_code != b.m_code;
|
|
|
}
|
|
|
|
|
|
- /// Compare.
|
|
|
Bool operator!=(I32 code) const
|
|
|
{
|
|
|
return m_code != code;
|
|
|
}
|
|
|
|
|
|
- /// Check if it is an error.
|
|
|
+ // Check if it is an error.
|
|
|
explicit operator Bool() const
|
|
|
{
|
|
|
if(m_code != kNone) [[unlikely]]
|
|
|
@@ -189,19 +179,17 @@ public:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// @privatesection
|
|
|
- /// @{
|
|
|
+ // Private
|
|
|
I32 _getCode() const
|
|
|
{
|
|
|
return m_code;
|
|
|
}
|
|
|
- /// @}
|
|
|
|
|
|
private:
|
|
|
I32 m_code = kNone;
|
|
|
};
|
|
|
|
|
|
-/// Macro to check if a method/function returned an error. It will return on error.
|
|
|
+// Macro to check if a method/function returned an error. It will return on error.
|
|
|
#define ANKI_CHECK(x_) \
|
|
|
do \
|
|
|
{ \
|
|
|
@@ -212,14 +200,14 @@ private:
|
|
|
} \
|
|
|
} while(0)
|
|
|
|
|
|
-/// Macro to check if a method/function returned an error. It will abort on error.
|
|
|
+// Macro to check if a method/function returned an error. It will abort on error.
|
|
|
#define ANKI_CHECKF(x_) \
|
|
|
if(x_) \
|
|
|
{ \
|
|
|
ANKI_LOGF("Failed and won't recover"); \
|
|
|
}
|
|
|
|
|
|
-/// Macro to check if a method/function returned an error.
|
|
|
+// Macro to check if a method/function returned an error.
|
|
|
#define ANKI_CHECK_AND_IGNORE(x_) \
|
|
|
do \
|
|
|
{ \
|
|
|
@@ -232,8 +220,7 @@ private:
|
|
|
# define ANKI_DEBUG_CODE(x)
|
|
|
#endif
|
|
|
|
|
|
-/// @name AnKi type user literals.
|
|
|
-/// @{
|
|
|
+// AnKi type user literals.
|
|
|
inline constexpr U8 operator""_U8(unsigned long long arg) noexcept
|
|
|
{
|
|
|
return U8(arg);
|
|
|
@@ -258,10 +245,8 @@ inline constexpr PtrSize operator""_PtrSize(unsigned long long arg) noexcept
|
|
|
{
|
|
|
return PtrSize(arg);
|
|
|
}
|
|
|
-/// @}
|
|
|
|
|
|
-/// @name Size user literals
|
|
|
-/// @{
|
|
|
+// Size user literals
|
|
|
inline constexpr PtrSize operator""_B(unsigned long long int x)
|
|
|
{
|
|
|
return x;
|
|
|
@@ -281,10 +266,8 @@ inline constexpr PtrSize operator""_GB(unsigned long long int x)
|
|
|
{
|
|
|
return x * (1024 * 1024 * 1024);
|
|
|
}
|
|
|
-/// @}
|
|
|
|
|
|
-/// @name Time user literals
|
|
|
-/// @{
|
|
|
+// Time user literals
|
|
|
inline constexpr Second operator""_hour(long double x)
|
|
|
{
|
|
|
return Second(x) * 60.0;
|
|
|
@@ -304,10 +287,8 @@ inline constexpr Second operator""_ns(long double x)
|
|
|
{
|
|
|
return Second(x) / 1000000000.0;
|
|
|
}
|
|
|
-/// @}
|
|
|
|
|
|
-/// @name Distance user literals
|
|
|
-/// @{
|
|
|
+// Distance user literals
|
|
|
inline constexpr F32 operator""_m(long double x)
|
|
|
{
|
|
|
return F32(x);
|
|
|
@@ -327,29 +308,49 @@ inline constexpr F32 operator""_mm(long double x)
|
|
|
{
|
|
|
return F32(x) / 1000.0f;
|
|
|
}
|
|
|
-/// @}
|
|
|
|
|
|
-/// @name Other user literals
|
|
|
-/// @{
|
|
|
+// @name Other user literals
|
|
|
inline constexpr F32 operator""_degrees(long double x)
|
|
|
{
|
|
|
constexpr F32 kPi = 3.14159265358979323846f;
|
|
|
return F32(x) * (kPi / 180.0f);
|
|
|
}
|
|
|
-/// @}
|
|
|
|
|
|
-/// Convenience macro that defines the type of a class.
|
|
|
+// Convenience macro that defines the type of a class.
|
|
|
#define ANKI_DEFINE_CLASS_SELF(selfType) \
|
|
|
typedef auto _selfFn##selfType()->decltype(*this); \
|
|
|
using _SelfRef##selfType = decltype(((_selfFn##selfType*)0)()); \
|
|
|
using selfType = std::remove_reference<_SelfRef##selfType>::type;
|
|
|
|
|
|
-/// Instead of using bool to break a loop, which it's difficult to tell if it means stop or continue, use this enum
|
|
|
+// Instead of using bool to break a loop, which it's difficult to tell if it means stop or continue, use this enum
|
|
|
enum class FunctorContinue
|
|
|
{
|
|
|
kContinue,
|
|
|
kStop
|
|
|
};
|
|
|
-/// @}
|
|
|
+
|
|
|
+// Same thing as HLSL's asfloat
|
|
|
+ANKI_FORCE_INLINE F32 asF32(U32 i)
|
|
|
+{
|
|
|
+ F32 out;
|
|
|
+ memcpy(&out, &i, 4);
|
|
|
+ return out;
|
|
|
+}
|
|
|
+
|
|
|
+// Same thing as HLSL's asfloat
|
|
|
+ANKI_FORCE_INLINE F32 asF32(I32 i)
|
|
|
+{
|
|
|
+ F32 out;
|
|
|
+ memcpy(&out, &i, 4);
|
|
|
+ return out;
|
|
|
+}
|
|
|
+
|
|
|
+// Same thing as HLSL's asuint
|
|
|
+ANKI_FORCE_INLINE U32 asU32(F32 f)
|
|
|
+{
|
|
|
+ U32 out;
|
|
|
+ memcpy(&out, &f, 4);
|
|
|
+ return out;
|
|
|
+}
|
|
|
|
|
|
} // end namespace anki
|