1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#pragma once
#include "deimos/core/std.h"
#include "deimos/core/gsl.h"
#define deimos_StaticAssert(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
#define deimos_NO_COPY(TYPE) \
TYPE(const TYPE&) = delete; \
TYPE& operator=(const TYPE&) = delete;
#define deimos_NO_MOVE(TYPE) \
TYPE(TYPE&&) = delete; \
TYPE& operator=(TYPE&&) = delete;
#define deimos_NO_COPY_MOVE(TYPE) \
deimos_NO_COPY(TYPE); \
deimos_NO_MOVE(TYPE);
#define deimos_DEFAULT_COPY(TYPE) \
TYPE(const TYPE&) = default; \
TYPE& operator=(const TYPE&) = default;
#define deimos_DEFAULT_MOVE(TYPE) \
TYPE(TYPE&&) = default; \
TYPE& operator=(TYPE&&) = default;
#define deimos_DEFAULT_COPY_MOVE(TYPE) \
deimos_DEFAULT_COPY(TYPE); \
deimos_DEFAULT_MOVE(TYPE);
namespace deimos
{
struct uint128_t
{
uint64_t high;
uint64_t low;
constexpr bool operator==(const uint128_t& other) const = default;
};
struct SourceLocation
{
gsl::czstring file;
int32_t line;
constexpr SourceLocation( // NOLINT
gsl::czstring file_ = __builtin_FILE(),
int32_t line_ = __builtin_LINE()) :
file{file_},
line{line_}
{}
};
template<typename T> T Min(T a, T b) { return (a < b) ? a : b; }
template<typename T> T Max(T a, T b) { return (a > b) ? a : b; }
constexpr void MemoryCopy(void* dst, const void* src, int64_t size)
{
__builtin_memcpy(dst, src, (size_t)size);
}
template<typename T>
class Span
{
T* m_begin = nullptr;
int64_t m_size = 0;
public:
constexpr Span() = default;
~Span() = default;
deimos_DEFAULT_COPY_MOVE(Span);
constexpr Span(T* begin, int64_t size) :
m_begin{begin},
m_size{size}
{
Expects(size >= 0);
}
constexpr Span(std::initializer_list<T> list) :
m_begin{list.begin()},
m_size{(int64_t)list.size()}
{}
template<typename U>
requires std::convertible_to<U*, T*>
constexpr Span(const Span<U>& other) : // NOLINT(*-explicit-conversions)
m_begin{other.begin()},
m_size{other.size()}
{}
constexpr T* data() const { return m_begin; }
constexpr T* begin() const { return m_begin; }
constexpr T* end() const { return m_begin + m_size; } // NOLINT
constexpr int64_t size() const { return m_size; }
};
template<typename T>
inline Span<const std::byte> AsBytes(Span<T> span)
{
return { reinterpret_cast<const std::byte*>(span.data()), span.size() * (int64_t)sizeof(T) };
}
class StringView
{
const char* m_begin = nullptr;
int64_t m_size = 0;
public:
constexpr StringView() = default;
deimos_DEFAULT_COPY_MOVE(StringView);
~StringView() = default;
constexpr StringView(gsl::czstring str) : // NOLINT(*-explicit-conversions)
m_begin{str}, m_size{(int64_t)__builtin_strlen(str)}
{}
constexpr StringView(const char* begin, int64_t size) :
m_begin{begin}, m_size{size}
{}
constexpr const char* data() const { return m_begin; }
constexpr int64_t size() const { return m_size; }
};
inline Span<const std::byte> AsBytes(StringView span)
{
return { reinterpret_cast<const std::byte*>(span.data()), span.size() };
}
deimos_StaticAssert(std::is_trivially_destructible_v<StringView>);
deimos_StaticAssert(std::is_trivially_copyable_v<StringView>);
} // namespace deimos
|