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

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

View File

@@ -3,6 +3,7 @@
#include <optional>
#include <sstream>
#include <vector>
#include "../Defines.hpp"
#include "../Exception.hpp"
namespace ArbUt {
@@ -29,7 +30,7 @@ namespace ArbUt {
/// @brief Initialise a list from a memory range.
/// @param begin A pointer to the beginning 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.
inline void Clear() noexcept { _vector.clear(); }
@@ -149,7 +150,7 @@ namespace ArbUt {
/// @brief Return a raw 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.
/// @return A std::vector representation of the current list.
@@ -160,10 +161,10 @@ namespace ArbUt {
/// @brief Returns 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.
/// @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;
#
#define ENUM_GET_HIGHEST(x, name) \
if ((int64_t)name::x > highest) { \
highest = (int64_t)name::x; \
if ((i64)name::x > highest) { \
highest = (i64)name::x; \
}
#
#define ENUM_GET_LOWEST(x, name) \
if ((int64_t)name::x < lowest) { \
lowest = (int64_t)name::x; \
if ((i64)name::x < lowest) { \
lowest = (i64)name::x; \
}
#
#define ARRAY_NAME(x, name) name::x,
@@ -50,23 +50,21 @@
#define ALLOW_UINTEGER_OVERFLOW
#endif
#define ENUM_WITH_START_VALUE(name, type, startValue, values...) \
enum class name : type { \
MACRO_UTILS_FOR_EACH_WITH_VALUE(ENUM_VALUE, startValue + ___MACRO_UTILS_NARGS(values) - 1, values) \
}; \
class name##Helper { \
ALLOW_UINTEGER_OVERFLOW \
inline static uint32_t constexpr ConstHash(char const* input) noexcept { \
return *input ? static_cast<uint32_t>(*input) + 33 * ConstHash(input + 1) : 5381; \
inline static u32 constexpr ConstHash(char const* non_null input) noexcept { \
return *input ? static_cast<u32>(*input) + 33 * ConstHash(input + 1) : 5381; \
} \
inline static constexpr char charToLower(const char c) noexcept { \
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \
} \
ALLOW_UINTEGER_OVERFLOW \
inline static uint32_t constexpr ConstHashCI(char const* input) noexcept { \
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * ConstHashCI(input + 1) \
: 5381; \
inline static u32 constexpr ConstHashCI(char const* non_null input) noexcept { \
return charToLower(*input) ? static_cast<u32>(charToLower(*input)) + 33 * ConstHashCI(input + 1) : 5381; \
} \
\
public: \
@@ -74,13 +72,13 @@
switch (value) { MACRO_UTILS_FOR_EACH(ENUM_CASE, name, values) } \
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) \
return ParseCaseInsensitive(input); \
switch (ConstHash(input)) { MACRO_UTILS_FOR_EACH(ENUM_PARSE_CASE, name, values) } \
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) \
return TryParseCaseInsensitive(input, out); \
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 First() noexcept { return name::MACRO_UTILS_GET_FIRST(values); } \
constexpr static name Highest() noexcept { \
int64_t highest = -9223372036854775807; \
i64 highest = -9223372036854775807; \
MACRO_UTILS_FOR_EACH(ENUM_GET_HIGHEST, name, values) \
return (name)highest; \
} \
constexpr static name Lowest() noexcept { \
int64_t lowest = 9223372036854775807; \
i64 lowest = 9223372036854775807; \
MACRO_UTILS_FOR_EACH(ENUM_GET_LOWEST, name, values) \
return (name)lowest; \
} \
\
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) } \
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) } \
return false; \
} \

View File

@@ -1,7 +1,8 @@
#include "ErrorHelpers.hpp"
#include "Defines.hpp"
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;
error << "[" << file_name(location.file_name()) << ":" << location.line() << "] ENSURE FAILED: \"";
error << exp << "\"";

View File

@@ -6,6 +6,7 @@
#include <source_location>
#endif
#include <sstream>
#include "Defines.hpp"
#include "Exception.hpp"
#if defined(__clang__)
@@ -19,8 +20,8 @@ namespace ArbUt {
/// @brief Helper class for multiple error handling
class __ErrorHelpers {
static constexpr const char* file_name(const char* path) {
const char* file = path;
static constexpr const char* non_null file_name(const char* non_null path) {
const char* non_null file = path;
while (*path != 0) {
if (*path++ == '/') {
file = path;
@@ -31,10 +32,10 @@ namespace ArbUt {
public:
/// @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
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
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;
while (*path != 0) {
if (*path++ == '/') {
@@ -63,7 +63,7 @@ namespace ArbUt {
}
/// @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();
}

View File

@@ -1,14 +1,10 @@
#ifndef 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.
#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
#include <pcg_random.hpp>
@@ -17,6 +13,10 @@
#pragma clang attribute pop
#endif
#include <chrono>
#include <cstdint>
#include <random>
#include "Ensure.hpp"
namespace ArbUt {
/// @brief A helper class for getting random numbers.
@@ -43,60 +43,52 @@ namespace ArbUt {
inline RandomT& GetRandomEngine() noexcept { return _rng; }
/// @brief Gets a random float between 0.0 and 1.0.
[[nodiscard]] inline constexpr float GetFloat() noexcept {
return static_cast<float>(GetDouble());
}
[[nodiscard]] inline constexpr f32 GetFloat() noexcept { return static_cast<float>(GetDouble()); }
/// @brief Gets a random double between 0.0 and 1.0.
[[nodiscard]] inline constexpr double GetDouble() noexcept {
return _distribution(_rng);
}
[[nodiscard]] inline constexpr f64 GetDouble() noexcept { return _distribution(_rng); }
/// @brief Gets a random 32 bit integer
inline constexpr int32_t Get() noexcept {
return static_cast<int32_t>(_rng());
}
inline constexpr i32 Get() noexcept { return static_cast<i32>(_rng()); }
/// @brief Gets a random 32 bit integer between 0, and given max parameter.
/// @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);
std::uniform_int_distribution<int32_t> distribution(0, max - 1);
std::uniform_int_distribution<i32> distribution(0, max - 1);
return distribution(_rng);
}
/// @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 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);
std::uniform_int_distribution<int32_t> distribution(min, max - 1);
std::uniform_int_distribution<i32> distribution(min, max - 1);
return distribution(_rng);
}
/// @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.
/// @param max The exclusive max value the random value should be.
[[nodiscard]] inline uint32_t GetUnsigned(uint32_t max) noexcept {
std::uniform_int_distribution<uint32_t> distribution(0, max - 1);
[[nodiscard]] inline u32 GetUnsigned(u32 max) noexcept {
std::uniform_int_distribution<u32> distribution(0, max - 1);
return distribution(_rng);
}
/// @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 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);
std::uniform_int_distribution<uint32_t> distribution(min, max - 1);
std::uniform_int_distribution<u32> distribution(min, max - 1);
return distribution(_rng);
}
/// @brief The seed the random class is generating from.
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept {
return _seed;
}
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { return _seed; }
};
/// @brief Implementation of the BaseRandom class with pcg32 as random number generator.
@@ -109,5 +101,4 @@ namespace ArbUt {
};
}
#endif // ARBUTILS_RANDOM_HPP

View File

@@ -3,6 +3,7 @@
#include <cstdint>
#include <sstream>
#include <string_view>
#include "../Defines.hpp"
/// \defgroup Strings Strings
/// \brief Group of non-editable strings with faster hashing.
@@ -14,20 +15,20 @@ namespace ArbUt {
class BasicStringView {
protected:
size_t _length = 0;
uint32_t _hash = 0;
u32 _hash = 0;
/// @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:
/// @brief The amount of characters of the string.
[[nodiscard]] inline constexpr size_t Length() const noexcept { return _length; }
/// @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.
[[nodiscard]] inline constexpr std::size_t operator()() const noexcept { return _hash; }
/// @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
[[nodiscard]] inline constexpr bool operator==(const BasicStringView& rhs) const noexcept {
return _hash == rhs._hash;

View File

@@ -3,6 +3,7 @@
#include <cstring>
#include <memory>
#include "../Ensure.hpp"
#include "BasicStringView.hpp"
#if WINDOWS
@@ -13,21 +14,22 @@
namespace ArbUt {
class __ConstStringCharHolder {
char* _value = 0;
char* non_null _value = 0;
__ConstStringCharHolder(const __ConstStringCharHolder& o) = delete;
__ConstStringCharHolder& operator=(const __ConstStringCharHolder& other) = delete;
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);
}
~__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,
0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
@@ -59,14 +61,14 @@ constexpr uint32_t crc_table[256] = {
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
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) {
uint32_t crc = 0xffffffff;
static u32 constexpr Hash(std::string_view input) {
u32 crc = 0xffffffff;
for (auto c : input) {
crc = (crc >> 8) ^ crc_table[(crc ^ charToLower(c)) & 0xff];
}
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 {
/// \ingroup Strings
@@ -81,12 +83,12 @@ namespace ArbUt {
public:
/// @brief Instantiate a StringView using a 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))) {}
/// @brief Instantiate a StringView using a C string, as well as it's length.
/// @param str A null-terminated 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)) {}
StringView() noexcept : BasicStringView(0, Hash("")) {}
@@ -99,7 +101,7 @@ namespace ArbUt {
/// @param other Other StringView
/// @param c A null-terminated 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)) {}
/// @brief Assignment operator.
@@ -117,7 +119,7 @@ namespace ArbUt {
/// @brief Returns 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.
/// @return std::string_view.
[[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 {
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* 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* non_null rhs) const noexcept final { return _hash != Hash(rhs); }
/// @brief Calculates the hash for a given C string.
/// @param val A null-terminated C 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);
}
/// @brief Calculates the hash for a given std string.
/// @param val A std string.
/// @return A hash of the given string.
[[maybe_unused]] [[nodiscard]] inline static constexpr uint32_t
CalculateHash(const std::string_view& val) noexcept {
[[maybe_unused]] [[nodiscard]] inline static constexpr u32 CalculateHash(const std::string_view& val) noexcept {
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.
class StringViewLiteral final : public BasicStringView {
private:
const char* _str;
const char* non_null _str;
public:
/// @brief Compile time initialisation of a StringViewLiteral.
/// @param str A null terminated C 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) {}
/// @brief Compile time initialisation of a StringViewLiteral. Length is calculated at compile.
/// @param str A null terminated C string.
constexpr StringViewLiteral(const char* str) noexcept : StringViewLiteral(str, CalcLength(str)){};
[[nodiscard]] inline constexpr const char* c_str() const noexcept final { return _str; }
constexpr StringViewLiteral(const char* non_null str) noexcept : StringViewLiteral(str, CalcLength(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 {
return std::string_view(_str, _length);
}
@@ -38,8 +38,8 @@ namespace ArbUt {
inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final {
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* 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* 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);
}
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);
}

View File

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