Expand on the use of defines and non_null/nullable
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2022-03-23 12:56:12 +01:00
parent 0031804fe8
commit 9eca4fa9bb
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
17 changed files with 114 additions and 124 deletions

View File

@ -16,21 +16,21 @@ export float Arbutils_Random_GetFloat(ArbUt::Random* p) { return p->GetFloat();
/// @brief Returns a random double between 0.0 and 1.0 using a random object. /// @brief Returns a random double between 0.0 and 1.0 using a random object.
export double Arbutils_Random_GetDouble(ArbUt::Random* p) { return p->GetDouble(); } export double Arbutils_Random_GetDouble(ArbUt::Random* p) { return p->GetDouble(); }
/// @brief Returns a random a random 32 bit integer using a random object. /// @brief Returns a random a random 32 bit integer using a random object.
export int32_t Arbutils_Random_Get(ArbUt::Random* p) { return p->Get(); } export i32 Arbutils_Random_Get(ArbUt::Random* p) { return p->Get(); }
/// @brief Gets a random 32 bit integer with a given max. Returns a status code where 0 is Ok, and passes the output to the out parameter. /// @brief Gets a random 32 bit integer with a given max. Returns a status code where 0 is Ok, and passes the output to the out parameter.
export uint8_t Arbutils_Random_GetWithMax(ArbUt::Random* p, int32_t max, int32_t& out) { Try(out = p->Get(max);) } export u8 Arbutils_Random_GetWithMax(ArbUt::Random* p, i32 max, i32& out) { Try(out = p->Get(max);) }
/// @brief Gets a random 32 bit integer with a given min and max. Returns a status code where 0 is Ok, and passes the output to the out parameter. /// @brief Gets a random 32 bit integer with a given min and max. Returns a status code where 0 is Ok, and passes the output to the out parameter.
export uint8_t Arbutils_Random_GetInLimits(ArbUt::Random* p, int32_t min, int32_t max, int32_t& out) { export u8 Arbutils_Random_GetInLimits(ArbUt::Random* p, i32 min, i32 max, i32& out) {
Try(out = p->Get(min, max);) Try(out = p->Get(min, max);)
} }
/// @brief Returns a random a random 32 bit unsigned integer using a random object. /// @brief Returns a random a random 32 bit unsigned integer using a random object.
export uint32_t Arbutils_Random_GetUnsigned(ArbUt::Random* p) { return p->GetUnsigned(); } export u32 Arbutils_Random_GetUnsigned(ArbUt::Random* p) { return p->GetUnsigned(); }
/// @brief Gets a random 32 bit unsigned integer with a given max. Returns a status code where 0 is Ok, and passes the output to the out parameter. /// @brief Gets a random 32 bit unsigned integer with a given max. Returns a status code where 0 is Ok, and passes the output to the out parameter.
export uint8_t Arbutils_Random_GetUnsignedWithMax(ArbUt::Random* p, uint32_t max, uint32_t& out) { export u8 Arbutils_Random_GetUnsignedWithMax(ArbUt::Random* p, u32 max, u32& out) {
Try(out = p->GetUnsigned(max);) Try(out = p->GetUnsigned(max);)
} }
/// @brief Gets a random 32 bit unsigned integer with a given min and max. Returns a status code where 0 is Ok, and passes the output to the out parameter. /// @brief Gets a random 32 bit unsigned integer with a given min and max. Returns a status code where 0 is Ok, and passes the output to the out parameter.
export uint8_t Arbutils_Random_GetUnsignedInLimits(ArbUt::Random* p, uint32_t min, uint32_t max, uint32_t& out) { export u8 Arbutils_Random_GetUnsignedInLimits(ArbUt::Random* p, u32 min, u32 max, u32& out) {
Try(out = p->GetUnsigned(min, max);) Try(out = p->GetUnsigned(min, max);)
} }

View File

@ -3,6 +3,7 @@
#include <optional> #include <optional>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include "../Defines.hpp"
#include "../Exception.hpp" #include "../Exception.hpp"
namespace ArbUt { namespace ArbUt {
@ -29,7 +30,7 @@ namespace ArbUt {
/// @brief Initialise a list from a memory range. /// @brief Initialise a list from a memory range.
/// @param begin A pointer to the beginning of the memory range. /// @param begin A pointer to the beginning of the memory range.
/// @param end A pointer to the end of the memory range. /// @param end A pointer to the end of the memory range.
List(const ValueT* begin, const ValueT* end) noexcept : _vector(begin, end) {} List(const ValueT* non_null begin, const ValueT* non_null end) noexcept : _vector(begin, end) {}
/// @brief Removes all items from the list. /// @brief Removes all items from the list.
inline void Clear() noexcept { _vector.clear(); } inline void Clear() noexcept { _vector.clear(); }
@ -149,7 +150,7 @@ namespace ArbUt {
/// @brief Return a raw pointer to the beginning of the list. /// @brief Return a raw pointer to the beginning of the list.
/// @return A raw array pointer to the beginning of the list. /// @return A raw array pointer to the beginning of the list.
const ValueT* RawData() const noexcept { return _vector.data(); } const ValueT* non_null RawData() const noexcept { return _vector.data(); }
/// @brief Returns a std::vector representation of the current list. /// @brief Returns a std::vector representation of the current list.
/// @return A std::vector representation of the current list. /// @return A std::vector representation of the current list.
@ -160,10 +161,10 @@ namespace ArbUt {
/// @brief Returns a raw pointer to the current list. /// @brief Returns a raw pointer to the current list.
/// @return A raw pointer to the current list. /// @return A raw pointer to the current list.
inline const List<ValueT>* GetListPointer() const { return this; } inline const List<ValueT>* non_null GetListPointer() const { return this; }
/// @brief Returns a raw pointer to the current list. /// @brief Returns a raw pointer to the current list.
/// @return A raw pointer to the current list. /// @return A raw pointer to the current list.
inline List<ValueT>* GetListPointer() { return this; } inline List<ValueT>* non_null GetListPointer() { return this; }
}; };
} }

View File

@ -27,13 +27,13 @@
return true; return true;
# #
#define ENUM_GET_HIGHEST(x, name) \ #define ENUM_GET_HIGHEST(x, name) \
if ((int64_t)name::x > highest) { \ if ((i64)name::x > highest) { \
highest = (int64_t)name::x; \ highest = (i64)name::x; \
} }
# #
#define ENUM_GET_LOWEST(x, name) \ #define ENUM_GET_LOWEST(x, name) \
if ((int64_t)name::x < lowest) { \ if ((i64)name::x < lowest) { \
lowest = (int64_t)name::x; \ lowest = (i64)name::x; \
} }
# #
#define ARRAY_NAME(x, name) name::x, #define ARRAY_NAME(x, name) name::x,
@ -50,23 +50,21 @@
#define ALLOW_UINTEGER_OVERFLOW #define ALLOW_UINTEGER_OVERFLOW
#endif #endif
#define ENUM_WITH_START_VALUE(name, type, startValue, values...) \ #define ENUM_WITH_START_VALUE(name, type, startValue, values...) \
enum class name : type { \ enum class name : type { \
MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \ MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \
}; \ }; \
class name##Helper { \ class name##Helper { \
ALLOW_UINTEGER_OVERFLOW \ ALLOW_UINTEGER_OVERFLOW \
inline static uint32_t constexpr ConstHash(char const* input) noexcept { \ inline static u32 constexpr ConstHash(char const* non_null input) noexcept { \
return *input ? static_cast<uint32_t>(*input) + 33 * ConstHash(input + 1) : 5381; \ return *input ? static_cast<u32>(*input) + 33 * ConstHash(input + 1) : 5381; \
} \ } \
inline static constexpr char charToLower(const char c) noexcept { \ inline static constexpr char charToLower(const char c) noexcept { \
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \ return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \
} \ } \
ALLOW_UINTEGER_OVERFLOW \ ALLOW_UINTEGER_OVERFLOW \
inline static uint32_t constexpr ConstHashCI(char const* input) noexcept { \ inline static u32 constexpr ConstHashCI(char const* non_null input) noexcept { \
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * ConstHashCI(input + 1) \ return charToLower(*input) ? static_cast<u32>(charToLower(*input)) + 33 * ConstHashCI(input + 1) : 5381; \
: 5381; \
} \ } \
\ \
public: \ public: \
@ -74,13 +72,13 @@
switch (value) { MACRO_UTILS_FOR_EACH(ENUM_CASE, name, values) } \ switch (value) { MACRO_UTILS_FOR_EACH(ENUM_CASE, name, values) } \
return "out of bounds"_cnc; \ return "out of bounds"_cnc; \
} \ } \
constexpr static name Parse(const char* input, bool caseInsensitive = false) { \ constexpr static name Parse(const char* non_null input, bool caseInsensitive = false) { \
if (caseInsensitive) \ if (caseInsensitive) \
return ParseCaseInsensitive(input); \ return ParseCaseInsensitive(input); \
switch (ConstHash(input)) { MACRO_UTILS_FOR_EACH(ENUM_PARSE_CASE, name, values) } \ switch (ConstHash(input)) { MACRO_UTILS_FOR_EACH(ENUM_PARSE_CASE, name, values) } \
throw std::runtime_error("Invalid " #name " string."); \ throw std::runtime_error("Invalid " #name " string."); \
} \ } \
constexpr static bool TryParse(const char* input, name& out, bool caseInsensitive = false) noexcept { \ constexpr static bool TryParse(const char* non_null input, name& out, bool caseInsensitive = false) noexcept { \
if (caseInsensitive) \ if (caseInsensitive) \
return TryParseCaseInsensitive(input, out); \ return TryParseCaseInsensitive(input, out); \
switch (ConstHash(input)) { MACRO_UTILS_FOR_EACH(ENUM_TRY_PARSE_CASE, name, values) } \ switch (ConstHash(input)) { MACRO_UTILS_FOR_EACH(ENUM_TRY_PARSE_CASE, name, values) } \
@ -90,22 +88,22 @@
constexpr static name Last() noexcept { return name::MACRO_UTILS_GET_LAST(values); } \ constexpr static name Last() noexcept { return name::MACRO_UTILS_GET_LAST(values); } \
constexpr static name First() noexcept { return name::MACRO_UTILS_GET_FIRST(values); } \ constexpr static name First() noexcept { return name::MACRO_UTILS_GET_FIRST(values); } \
constexpr static name Highest() noexcept { \ constexpr static name Highest() noexcept { \
int64_t highest = -9223372036854775807; \ i64 highest = -9223372036854775807; \
MACRO_UTILS_FOR_EACH(ENUM_GET_HIGHEST, name, values) \ MACRO_UTILS_FOR_EACH(ENUM_GET_HIGHEST, name, values) \
return (name)highest; \ return (name)highest; \
} \ } \
constexpr static name Lowest() noexcept { \ constexpr static name Lowest() noexcept { \
int64_t lowest = 9223372036854775807; \ i64 lowest = 9223372036854775807; \
MACRO_UTILS_FOR_EACH(ENUM_GET_LOWEST, name, values) \ MACRO_UTILS_FOR_EACH(ENUM_GET_LOWEST, name, values) \
return (name)lowest; \ return (name)lowest; \
} \ } \
\ \
private: \ private: \
constexpr static name ParseCaseInsensitive(const char* input) { \ constexpr static name ParseCaseInsensitive(const char* non_null input) { \
switch (ConstHashCI(input)) { MACRO_UTILS_FOR_EACH(ENUM_PARSE_CASE_INSENSITIVE, name, values) } \ switch (ConstHashCI(input)) { MACRO_UTILS_FOR_EACH(ENUM_PARSE_CASE_INSENSITIVE, name, values) } \
throw std::runtime_error("Invalid " #name " string."); \ throw std::runtime_error("Invalid " #name " string."); \
} \ } \
constexpr static bool TryParseCaseInsensitive(const char* input, name& out) noexcept { \ constexpr static bool TryParseCaseInsensitive(const char* non_null input, name& out) noexcept { \
switch (ConstHashCI(input)) { MACRO_UTILS_FOR_EACH(ENUM_TRY_PARSE_CASE_INSENSITIVE, name, values) } \ switch (ConstHashCI(input)) { MACRO_UTILS_FOR_EACH(ENUM_TRY_PARSE_CASE_INSENSITIVE, name, values) } \
return false; \ return false; \
} \ } \

View File

@ -1,7 +1,8 @@
#include "ErrorHelpers.hpp" #include "ErrorHelpers.hpp"
#include "Defines.hpp"
namespace ArbUt { namespace ArbUt {
Exception __ErrorHelpers::CreateEnsureError(const char* exp, const std::source_location& location) { Exception __ErrorHelpers::CreateEnsureError(const char* non_null exp, const std::source_location& location) {
std::stringstream error; std::stringstream error;
error << "[" << file_name(location.file_name()) << ":" << location.line() << "] ENSURE FAILED: \""; error << "[" << file_name(location.file_name()) << ":" << location.line() << "] ENSURE FAILED: \"";
error << exp << "\""; error << exp << "\"";

View File

@ -6,6 +6,7 @@
#include <source_location> #include <source_location>
#endif #endif
#include <sstream> #include <sstream>
#include "Defines.hpp"
#include "Exception.hpp" #include "Exception.hpp"
#if defined(__clang__) #if defined(__clang__)
@ -19,8 +20,8 @@ namespace ArbUt {
/// @brief Helper class for multiple error handling /// @brief Helper class for multiple error handling
class __ErrorHelpers { class __ErrorHelpers {
static constexpr const char* file_name(const char* path) { static constexpr const char* non_null file_name(const char* non_null path) {
const char* file = path; const char* non_null file = path;
while (*path != 0) { while (*path != 0) {
if (*path++ == '/') { if (*path++ == '/') {
file = path; file = path;
@ -31,10 +32,10 @@ namespace ArbUt {
public: public:
/// @brief Create an error for the Ensure macro /// @brief Create an error for the Ensure macro
static ArbUt::Exception CreateEnsureError(const char* exp, const std::source_location& location); static ArbUt::Exception CreateEnsureError(const char* non_null exp, const std::source_location& location);
/// @brief Create an error for the Throw macro /// @brief Create an error for the Throw macro
static ArbUt::Exception CreateThrowError(const char* exp, const std::source_location& location); static ArbUt::Exception CreateThrowError(const char* non_null exp, const std::source_location& location);
}; };
}; };

View File

@ -20,7 +20,7 @@ namespace std {
} }
#endif #endif
static constexpr const char* file_name(const char* path) { static constexpr const char* non_null file_name(const char* non_null path) {
const char* file = path; const char* file = path;
while (*path != 0) { while (*path != 0) {
if (*path++ == '/') { if (*path++ == '/') {
@ -63,7 +63,7 @@ namespace ArbUt {
} }
/// @brief Returns the error message of the exception. /// @brief Returns the error message of the exception.
[[nodiscard]] const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW final { [[nodiscard]] const char* non_null what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW final {
return logic_error::what(); return logic_error::what();
} }

View File

@ -1,14 +1,10 @@
#ifndef ARBUTILS_RANDOM_HPP #ifndef ARBUTILS_RANDOM_HPP
#define ARBUTILS_RANDOM_HPP #define ARBUTILS_RANDOM_HPP
#include <chrono>
#include <cstdint>
#include <random>
#include "Ensure.hpp"
// PCG uses unsigned shifts, and overflows a lot. Disable the sanitizer for that. // PCG uses unsigned shifts, and overflows a lot. Disable the sanitizer for that.
#if defined(__clang__) #if defined(__clang__)
#pragma clang attribute push (__attribute__((no_sanitize("unsigned-shift-base", "unsigned-integer-overflow"))), apply_to=function) #pragma clang attribute push(__attribute__((no_sanitize("unsigned-shift-base", "unsigned-integer-overflow"))), \
apply_to = function)
#endif #endif
#include <pcg_random.hpp> #include <pcg_random.hpp>
@ -17,6 +13,10 @@
#pragma clang attribute pop #pragma clang attribute pop
#endif #endif
#include <chrono>
#include <cstdint>
#include <random>
#include "Ensure.hpp"
namespace ArbUt { namespace ArbUt {
/// @brief A helper class for getting random numbers. /// @brief A helper class for getting random numbers.
@ -43,60 +43,52 @@ namespace ArbUt {
inline RandomT& GetRandomEngine() noexcept { return _rng; } inline RandomT& GetRandomEngine() noexcept { return _rng; }
/// @brief Gets a random float between 0.0 and 1.0. /// @brief Gets a random float between 0.0 and 1.0.
[[nodiscard]] inline constexpr float GetFloat() noexcept { [[nodiscard]] inline constexpr f32 GetFloat() noexcept { return static_cast<float>(GetDouble()); }
return static_cast<float>(GetDouble());
}
/// @brief Gets a random double between 0.0 and 1.0. /// @brief Gets a random double between 0.0 and 1.0.
[[nodiscard]] inline constexpr double GetDouble() noexcept { [[nodiscard]] inline constexpr f64 GetDouble() noexcept { return _distribution(_rng); }
return _distribution(_rng);
}
/// @brief Gets a random 32 bit integer /// @brief Gets a random 32 bit integer
inline constexpr int32_t Get() noexcept { inline constexpr i32 Get() noexcept { return static_cast<i32>(_rng()); }
return static_cast<int32_t>(_rng());
}
/// @brief Gets a random 32 bit integer between 0, and given max parameter. /// @brief Gets a random 32 bit integer between 0, and given max parameter.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline int32_t Get(int32_t max) { [[nodiscard]] inline i32 Get(i32 max) {
Ensure(max > 0); Ensure(max > 0);
std::uniform_int_distribution<int32_t> distribution(0, max - 1); std::uniform_int_distribution<i32> distribution(0, max - 1);
return distribution(_rng); return distribution(_rng);
} }
/// @brief Gets a random 32 bit integer between given min and max parameters. /// @brief Gets a random 32 bit integer between given min and max parameters.
/// @param min The inclusive min value the random value should be. /// @param min The inclusive min value the random value should be.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline int32_t Get(int32_t min, int32_t max) { [[nodiscard]] inline i32 Get(i32 min, i32 max) {
Ensure(max > min); Ensure(max > min);
std::uniform_int_distribution<int32_t> distribution(min, max - 1); std::uniform_int_distribution<i32> distribution(min, max - 1);
return distribution(_rng); return distribution(_rng);
} }
/// @brief Gets a random 32 bit unsigned integer between 0 and max unsigned int. /// @brief Gets a random 32 bit unsigned integer between 0 and max unsigned int.
[[nodiscard]] inline constexpr uint32_t GetUnsigned() noexcept { return _rng(); } [[nodiscard]] inline constexpr u32 GetUnsigned() noexcept { return _rng(); }
/// @brief Gets a random 32 bit unsigned integer between 0, and given max parameter. /// @brief Gets a random 32 bit unsigned integer between 0, and given max parameter.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline uint32_t GetUnsigned(uint32_t max) noexcept { [[nodiscard]] inline u32 GetUnsigned(u32 max) noexcept {
std::uniform_int_distribution<uint32_t> distribution(0, max - 1); std::uniform_int_distribution<u32> distribution(0, max - 1);
return distribution(_rng); return distribution(_rng);
} }
/// @brief Gets a random 32 bit unsigned integer between given min and max parameters. /// @brief Gets a random 32 bit unsigned integer between given min and max parameters.
/// @param min The inclusive min value the random value should be. /// @param min The inclusive min value the random value should be.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline uint32_t GetUnsigned(uint32_t min, uint32_t max) { [[nodiscard]] inline u32 GetUnsigned(u32 min, u32 max) {
Ensure(max > min); Ensure(max > min);
std::uniform_int_distribution<uint32_t> distribution(min, max - 1); std::uniform_int_distribution<u32> distribution(min, max - 1);
return distribution(_rng); return distribution(_rng);
} }
/// @brief The seed the random class is generating from. /// @brief The seed the random class is generating from.
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { [[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { return _seed; }
return _seed;
}
}; };
/// @brief Implementation of the BaseRandom class with pcg32 as random number generator. /// @brief Implementation of the BaseRandom class with pcg32 as random number generator.
@ -109,5 +101,4 @@ namespace ArbUt {
}; };
} }
#endif // ARBUTILS_RANDOM_HPP #endif // ARBUTILS_RANDOM_HPP

View File

@ -3,6 +3,7 @@
#include <cstdint> #include <cstdint>
#include <sstream> #include <sstream>
#include <string_view> #include <string_view>
#include "../Defines.hpp"
/// \defgroup Strings Strings /// \defgroup Strings Strings
/// \brief Group of non-editable strings with faster hashing. /// \brief Group of non-editable strings with faster hashing.
@ -14,20 +15,20 @@ namespace ArbUt {
class BasicStringView { class BasicStringView {
protected: protected:
size_t _length = 0; size_t _length = 0;
uint32_t _hash = 0; u32 _hash = 0;
/// @brief Construct a basic string view. /// @brief Construct a basic string view.
constexpr BasicStringView(size_t length, uint32_t hash) : _length(length), _hash(hash) {} constexpr BasicStringView(size_t length, u32 hash) : _length(length), _hash(hash) {}
public: public:
/// @brief The amount of characters of the string. /// @brief The amount of characters of the string.
[[nodiscard]] inline constexpr size_t Length() const noexcept { return _length; } [[nodiscard]] inline constexpr size_t Length() const noexcept { return _length; }
/// @brief The unique hash of the string. /// @brief The unique hash of the string.
[[nodiscard]] inline constexpr uint32_t GetHash() const noexcept { return _hash; } [[nodiscard]] inline constexpr u32 GetHash() const noexcept { return _hash; }
/// @brief The unique hash of the string. /// @brief The unique hash of the string.
[[nodiscard]] inline constexpr std::size_t operator()() const noexcept { return _hash; } [[nodiscard]] inline constexpr std::size_t operator()() const noexcept { return _hash; }
/// @brief The unique hash of the string. /// @brief The unique hash of the string.
[[nodiscard]] inline constexpr operator uint32_t() const noexcept { return _hash; } [[nodiscard]] inline constexpr operator u32() const noexcept { return _hash; }
/// @brief Check whether two StringViews are equal /// @brief Check whether two StringViews are equal
[[nodiscard]] inline constexpr bool operator==(const BasicStringView& rhs) const noexcept { [[nodiscard]] inline constexpr bool operator==(const BasicStringView& rhs) const noexcept {
return _hash == rhs._hash; return _hash == rhs._hash;

View File

@ -3,6 +3,7 @@
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include "../Ensure.hpp"
#include "BasicStringView.hpp" #include "BasicStringView.hpp"
#if WINDOWS #if WINDOWS
@ -13,21 +14,22 @@
namespace ArbUt { namespace ArbUt {
class __ConstStringCharHolder { class __ConstStringCharHolder {
char* _value = 0; char* non_null _value = 0;
__ConstStringCharHolder(const __ConstStringCharHolder& o) = delete; __ConstStringCharHolder(const __ConstStringCharHolder& o) = delete;
__ConstStringCharHolder& operator=(const __ConstStringCharHolder& other) = delete; __ConstStringCharHolder& operator=(const __ConstStringCharHolder& other) = delete;
public: public:
__ConstStringCharHolder(const char* value, size_t length) noexcept : _value(new char[length + 1]) { __ConstStringCharHolder(const char* non_null value, size_t length) : _value(new char[length + 1]) {
EnsureNotNull(value);
strncpy(_value, value, length + 1); strncpy(_value, value, length + 1);
} }
~__ConstStringCharHolder() noexcept { delete[] _value; } ~__ConstStringCharHolder() noexcept { delete[] _value; }
inline constexpr const char* GetValue() const noexcept { return _value; } inline constexpr const char* non_null GetValue() const noexcept { return _value; }
}; };
} }
constexpr uint32_t crc_table[256] = { constexpr u32 crc_table[256] = {
0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832,
0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
@ -59,14 +61,14 @@ constexpr uint32_t crc_table[256] = {
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; } inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; }
static uint32_t constexpr Hash(std::string_view input) { static u32 constexpr Hash(std::string_view input) {
uint32_t crc = 0xffffffff; u32 crc = 0xffffffff;
for (auto c : input) { for (auto c : input) {
crc = (crc >> 8) ^ crc_table[(crc ^ charToLower(c)) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ charToLower(c)) & 0xff];
} }
return crc ^ 0xffffffff; return crc ^ 0xffffffff;
}; };
static int constexpr CalcLength(const char* str) { return *str ? 1 + CalcLength(str + 1) : 0; } static int constexpr CalcLength(const char* non_null str) { return *str ? 1 + CalcLength(str + 1) : 0; }
namespace ArbUt { namespace ArbUt {
/// \ingroup Strings /// \ingroup Strings
@ -81,12 +83,12 @@ namespace ArbUt {
public: public:
/// @brief Instantiate a StringView using a C string. /// @brief Instantiate a StringView using a C string.
/// @param str A null-terminated C string. /// @param str A null-terminated C string.
StringView(const char* str) noexcept StringView(const char* non_null str)
: BasicStringView(CalcLength(str), Hash(str)), _str(new __ConstStringCharHolder(str, CalcLength(str))) {} : BasicStringView(CalcLength(str), Hash(str)), _str(new __ConstStringCharHolder(str, CalcLength(str))) {}
/// @brief Instantiate a StringView using a C string, as well as it's length. /// @brief Instantiate a StringView using a C string, as well as it's length.
/// @param str A null-terminated C string. /// @param str A null-terminated C string.
/// @param length The length of the C string /// @param length The length of the C string
StringView(const char* str, size_t length) noexcept StringView(const char* non_null str, size_t length)
: BasicStringView(length, Hash(str)), _str(new __ConstStringCharHolder(str, length)) {} : BasicStringView(length, Hash(str)), _str(new __ConstStringCharHolder(str, length)) {}
StringView() noexcept : BasicStringView(0, Hash("")) {} StringView() noexcept : BasicStringView(0, Hash("")) {}
@ -99,7 +101,7 @@ namespace ArbUt {
/// @param other Other StringView /// @param other Other StringView
/// @param c A null-terminated C string. /// @param c A null-terminated C string.
/// @param length The length of the C string. /// @param length The length of the C string.
StringView(const BasicStringView& other, const char* c, size_t length) noexcept StringView(const BasicStringView& other, const char* non_null c, size_t length) noexcept
: BasicStringView(length, other.GetHash()), _str(new __ConstStringCharHolder(c, length)) {} : BasicStringView(length, other.GetHash()), _str(new __ConstStringCharHolder(c, length)) {}
/// @brief Assignment operator. /// @brief Assignment operator.
@ -117,7 +119,7 @@ namespace ArbUt {
/// @brief Returns null-terminated C string. /// @brief Returns null-terminated C string.
/// @return Null-terminated C string. /// @return Null-terminated C string.
[[nodiscard]] inline const char* c_str() const noexcept final { return _str->GetValue(); } [[nodiscard]] inline const char* non_null c_str() const noexcept final { return _str->GetValue(); }
/// @brief Returns std string_view of internal C string. /// @brief Returns std string_view of internal C string.
/// @return std::string_view. /// @return std::string_view.
[[nodiscard]] inline std::string_view std_str() const noexcept final { return _str->GetValue(); } [[nodiscard]] inline std::string_view std_str() const noexcept final { return _str->GetValue(); }
@ -128,21 +130,20 @@ namespace ArbUt {
inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final { inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final {
return _hash != Hash(rhs.data()); return _hash != Hash(rhs.data());
} }
inline constexpr bool operator==(const char* rhs) const noexcept final { return _hash == Hash(rhs); } inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs); }
inline constexpr bool operator!=(const char* rhs) const noexcept final { return _hash != Hash(rhs); } inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs); }
/// @brief Calculates the hash for a given C string. /// @brief Calculates the hash for a given C string.
/// @param val A null-terminated C string. /// @param val A null-terminated C string.
/// @return A hash of the given string. /// @return A hash of the given string.
[[maybe_unused]] [[nodiscard]] inline static constexpr uint32_t CalculateHash(const char* val) noexcept { [[maybe_unused]] [[nodiscard]] inline static constexpr u32 CalculateHash(const char* non_null val) noexcept {
return Hash(val); return Hash(val);
} }
/// @brief Calculates the hash for a given std string. /// @brief Calculates the hash for a given std string.
/// @param val A std string. /// @param val A std string.
/// @return A hash of the given string. /// @return A hash of the given string.
[[maybe_unused]] [[nodiscard]] inline static constexpr uint32_t [[maybe_unused]] [[nodiscard]] inline static constexpr u32 CalculateHash(const std::string_view& val) noexcept {
CalculateHash(const std::string_view& val) noexcept {
return Hash(val.data()); return Hash(val.data());
} }

View File

@ -9,18 +9,18 @@ namespace ArbUt {
/// @brief A literal representation of a string view. Used for compile time string processing. /// @brief A literal representation of a string view. Used for compile time string processing.
class StringViewLiteral final : public BasicStringView { class StringViewLiteral final : public BasicStringView {
private: private:
const char* _str; const char* non_null _str;
public: public:
/// @brief Compile time initialisation of a StringViewLiteral. /// @brief Compile time initialisation of a StringViewLiteral.
/// @param str A null terminated C string. /// @param str A null terminated C string.
/// @param size A The length of the string. /// @param size A The length of the string.
constexpr StringViewLiteral(const char* str, size_t size) noexcept constexpr StringViewLiteral(const char* non_null str, size_t size) noexcept
: BasicStringView(size, Hash(str)), _str(str) {} : BasicStringView(size, Hash(str)), _str(str) {}
/// @brief Compile time initialisation of a StringViewLiteral. Length is calculated at compile. /// @brief Compile time initialisation of a StringViewLiteral. Length is calculated at compile.
/// @param str A null terminated C string. /// @param str A null terminated C string.
constexpr StringViewLiteral(const char* str) noexcept : StringViewLiteral(str, CalcLength(str)){}; constexpr StringViewLiteral(const char* non_null str) noexcept : StringViewLiteral(str, CalcLength(str)){};
[[nodiscard]] inline constexpr const char* c_str() const noexcept final { return _str; } [[nodiscard]] inline constexpr const char* non_null c_str() const noexcept final { return _str; }
[[nodiscard]] constexpr std::string_view std_str() const noexcept final { [[nodiscard]] constexpr std::string_view std_str() const noexcept final {
return std::string_view(_str, _length); return std::string_view(_str, _length);
} }
@ -38,8 +38,8 @@ namespace ArbUt {
inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final { inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final {
return _hash != Hash(rhs.data()); return _hash != Hash(rhs.data());
} }
inline constexpr bool operator==(const char* rhs) const noexcept final { return _hash == Hash(rhs); } inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs); }
inline constexpr bool operator!=(const char* rhs) const noexcept final { return _hash != Hash(rhs); } inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs); }
}; };
} }
@ -53,10 +53,10 @@ namespace std {
}; };
} }
inline constexpr ArbUt::StringViewLiteral operator"" _const_nocase(const char* c, size_t l) { inline constexpr ArbUt::StringViewLiteral operator"" _const_nocase(const char* non_null c, size_t l) {
return ArbUt::StringViewLiteral(c, l); return ArbUt::StringViewLiteral(c, l);
} }
inline constexpr ArbUt::StringViewLiteral operator"" _cnc(const char* c, size_t l) { inline constexpr ArbUt::StringViewLiteral operator"" _cnc(const char* non_null c, size_t l) {
return ArbUt::StringViewLiteral(c, l); return ArbUt::StringViewLiteral(c, l);
} }

View File

@ -1,6 +1,2 @@
#include "String/StringView.hpp" #include "String/StringView.hpp"
#include "String/StringViewLiteral.hpp" #include "String/StringViewLiteral.hpp"
namespace ArbUt {
[[deprecated("Moved to StringView")]] typedef StringView CaseInsensitiveConstString;
}

View File

@ -4,14 +4,14 @@
using namespace ArbUt; using namespace ArbUt;
TEST_CASE("Create Dictionary, insert values") { TEST_CASE("Create Dictionary, insert values") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
dic.Insert(2, 100); dic.Insert(2, 100);
dic.Insert(9, 2000); dic.Insert(9, 2000);
} }
TEST_CASE("Create Dictionary with initializer list") { TEST_CASE("Create Dictionary with initializer list") {
auto dic = Dictionary<int, int>({{5, 100}, {10, 200}, {50, 2}}); auto dic = Dictionary<i32, i32>({{5, 100}, {10, 200}, {50, 2}});
CHECK(dic.Get(5) == 100); CHECK(dic.Get(5) == 100);
CHECK(dic.Get(10) == 200); CHECK(dic.Get(10) == 200);
@ -19,7 +19,7 @@ TEST_CASE("Create Dictionary with initializer list") {
} }
TEST_CASE("Create Dictionary, insert values, get values") { TEST_CASE("Create Dictionary, insert values, get values") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
dic.Insert(2, 100); dic.Insert(2, 100);
dic.Insert(9, 2000); dic.Insert(9, 2000);
@ -30,7 +30,7 @@ TEST_CASE("Create Dictionary, insert values, get values") {
} }
TEST_CASE("Create Dictionary, insert values twice should throw") { TEST_CASE("Create Dictionary, insert values twice should throw") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
CHECK_THROWS(dic.Insert(10, 100)); CHECK_THROWS(dic.Insert(10, 100));
@ -38,7 +38,7 @@ TEST_CASE("Create Dictionary, insert values twice should throw") {
} }
TEST_CASE("Create Dictionary, insert value, then update value") { TEST_CASE("Create Dictionary, insert value, then update value") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
dic[10] = 200; dic[10] = 200;
@ -46,7 +46,7 @@ TEST_CASE("Create Dictionary, insert value, then update value") {
} }
TEST_CASE("Create Dictionary, insert value, try get value") { TEST_CASE("Create Dictionary, insert value, try get value") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
auto v = dic.TryGet(10); auto v = dic.TryGet(10);
CHECK(v.has_value()); CHECK(v.has_value());
@ -54,24 +54,24 @@ TEST_CASE("Create Dictionary, insert value, try get value") {
} }
TEST_CASE("Create Dictionary, insert value, try get non existing value") { TEST_CASE("Create Dictionary, insert value, try get non existing value") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
CHECK_FALSE(dic.TryGet(10).has_value()); CHECK_FALSE(dic.TryGet(10).has_value());
} }
TEST_CASE("Create Dictionary, insert value, Has") { TEST_CASE("Create Dictionary, insert value, Has") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
CHECK(dic.Has(10)); CHECK(dic.Has(10));
} }
TEST_CASE("Create Dictionary, set value") { TEST_CASE("Create Dictionary, set value") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Set(5, 100); dic.Set(5, 100);
CHECK(dic.Has(5)); CHECK(dic.Has(5));
} }
TEST_CASE("Create Dictionary, insert values, get count") { TEST_CASE("Create Dictionary, insert values, get count") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
dic.Insert(2, 100); dic.Insert(2, 100);
dic.Insert(9, 2000); dic.Insert(9, 2000);
@ -80,7 +80,7 @@ TEST_CASE("Create Dictionary, insert values, get count") {
} }
TEST_CASE("Create Dictionary, insert values, iterate over keys") { TEST_CASE("Create Dictionary, insert values, iterate over keys") {
auto dic = Dictionary<int, int>(5); auto dic = Dictionary<i32, i32>(5);
dic.Insert(10, 5); dic.Insert(10, 5);
dic.Insert(2, 100); dic.Insert(2, 100);
dic.Insert(9, 2000); dic.Insert(9, 2000);

View File

@ -2,11 +2,11 @@
#include "../src/Ensure.hpp" #include "../src/Ensure.hpp"
void TestWrapper(bool wrapperExpression) { Ensure(wrapperExpression) } void TestWrapper(bool wrapperExpression) { Ensure(wrapperExpression) }
void TestWrapperNotNull(void* value) { EnsureNotNull(value) } void TestWrapperNotNull(void* value) { EnsureNotNull(value) }
void TestWrapperEquals(int32_t a, int32_t b) { EnsureEquals(a, b) } void TestWrapperEquals(i32 a, i32 b) { EnsureEquals(a, b) }
void TestWrapperGreater(int32_t a, int32_t b) { EnsureGreater(a, b) } void TestWrapperGreater(i32 a, i32 b) { EnsureGreater(a, b) }
void TestWrapperGreaterEquals(int32_t a, int32_t b) { EnsureGreaterOrEquals(a, b) } void TestWrapperGreaterEquals(i32 a, i32 b) { EnsureGreaterOrEquals(a, b) }
void TestWrapperLess(int32_t a, int32_t b) { EnsureLess(a, b) } void TestWrapperLess(i32 a, i32 b) { EnsureLess(a, b) }
void TestWrapperLessEquals(int32_t a, int32_t b){EnsureLessOrEquals(a, b)} void TestWrapperLessEquals(i32 a, i32 b){EnsureLessOrEquals(a, b)}
TEST_CASE("Ensure succeeds if true") { TEST_CASE("Ensure succeeds if true") {
REQUIRE_NOTHROW(TestWrapper(true)); REQUIRE_NOTHROW(TestWrapper(true));

View File

@ -5,7 +5,7 @@
#include "../src/Enum.hpp" #include "../src/Enum.hpp"
#include "../src/MacroUtils.hpp" #include "../src/MacroUtils.hpp"
ENUM(TestEnum, uint8_t, Val1, Val2, Val3) ENUM(TestEnum, u8, Val1, Val2, Val3)
#define STATIC_REQUIRE(expr) \ #define STATIC_REQUIRE(expr) \
static_assert(expr); \ static_assert(expr); \

View File

@ -3,6 +3,6 @@
#include "../src/Memory/Memory.hpp" #include "../src/Memory/Memory.hpp"
using namespace ArbUt; using namespace ArbUt;
TEST_CASE("Scoped Pointer deletes child after out of scope") { auto a = ScopedPtr<uint32_t>(new uint32_t(100)); } TEST_CASE("Scoped Pointer deletes child after out of scope") { auto a = ScopedPtr<u32>(new u32(100)); }
#endif #endif

View File

@ -20,7 +20,7 @@ TEST_CASE("Compare compile time with CaseInsensitiveStringview") {
} }
TEST_CASE("Use insensitive const string in unordered_map") { TEST_CASE("Use insensitive const string in unordered_map") {
std::unordered_map<ArbUt::StringView, int32_t> map; std::unordered_map<ArbUt::StringView, i32> map;
map.insert({"foO"_cnc, 1}); map.insert({"foO"_cnc, 1});
map.insert({"bAR"_cnc, 5}); map.insert({"bAR"_cnc, 5});

View File

@ -4,17 +4,17 @@
using namespace ArbUt; using namespace ArbUt;
TEST_CASE("Create Unique Ptr list, append") { TEST_CASE("Create Unique Ptr list, append") {
auto ls = UniquePtrList<uint32_t>(); auto ls = UniquePtrList<u32>();
auto v1 = new uint32_t(100); auto v1 = new u32(100);
auto v2 = new uint32_t(5000); auto v2 = new u32(5000);
ls.Append(v1); ls.Append(v1);
ls.Append(v2); ls.Append(v2);
} }
TEST_CASE("Create Unique Ptr list, append, retrieve") { TEST_CASE("Create Unique Ptr list, append, retrieve") {
auto ls = UniquePtrList<uint32_t>(); auto ls = UniquePtrList<u32>();
auto v1 = new uint32_t(100); auto v1 = new u32(100);
auto v2 = new uint32_t(5000); auto v2 = new u32(5000);
ls.Append(v1); ls.Append(v1);
ls.Append(v2); ls.Append(v2);
REQUIRE(ls.Count() == 2); REQUIRE(ls.Count() == 2);
@ -25,9 +25,9 @@ TEST_CASE("Create Unique Ptr list, append, retrieve") {
} }
TEST_CASE("Create Unique Ptr list, append, iterate") { TEST_CASE("Create Unique Ptr list, append, iterate") {
auto ls = UniquePtrList<uint32_t>(); auto ls = UniquePtrList<u32>();
auto v1 = new uint32_t(100); auto v1 = new u32(100);
auto v2 = new uint32_t(5000); auto v2 = new u32(5000);
ls.Append(v1); ls.Append(v1);
ls.Append(v2); ls.Append(v2);
REQUIRE(ls.Count() == 2); REQUIRE(ls.Count() == 2);
@ -42,9 +42,9 @@ TEST_CASE("Create Unique Ptr list, append, iterate") {
} }
TEST_CASE("Test unique ptr list out of bounds") { TEST_CASE("Test unique ptr list out of bounds") {
auto ls = UniquePtrList<uint32_t>(); auto ls = UniquePtrList<u32>();
auto v1 = new uint32_t(100); auto v1 = new u32(100);
auto v2 = new uint32_t(5000); auto v2 = new u32(5000);
ls.Append(v1); ls.Append(v1);
ls.Append(v2); ls.Append(v2);
REQUIRE_THROWS(ls.At(2)); REQUIRE_THROWS(ls.At(2));