35 =welder::doc(
"The logical value class of a table column.")
49 =welder::doc(
"One column of a table schema: its name, value class, "
50 "integer shape, array length and key roles.")
52 [[=welder::mark::no_reassign,
53 =welder::doc(
"The column name: the snake_case spelling of the WoWDBDefs "
54 "column ('MapName' -> 'map_name'). This spelling is a stable "
55 "cross-release contract on every binding surface.")]]
56 const char*
name =
nullptr;
57 [[=welder::mark::no_reassign,
58 =welder::doc(
"The verbatim WoWDBDefs spelling of the column "
59 "('MapName_lang'); column_index accepts it as an alias. Empty for "
60 "columns without a DBD identity (reflection-derived schemas).")]]
64 [[=welder::doc(
"The logical value class.")]]
66 [[=welder::doc(
"Integer element width in bits; 32 for float/string refs.")]]
67 std::uint8_t
bits = 0;
68 [[=welder::doc(
"Integer signedness; false for non-Int columns.")]]
70 [[=welder::doc(
"Element count; 1 for scalar columns.")]]
72 [[=welder::doc(
"LocString language slots (8 or 16); 0 otherwise.")]]
74 [[=welder::doc(
"Whether this is the table's primary key ($id$).")]]
76 [[=welder::doc(
"Whether this is a relationship key ($relation$).")]]
78 [[=welder::doc(
"Whether the column holds no bytes inside the record "
79 "image ($noninline$).")]]
91 constexpr std::string_view
nameView()
const {
return name; }
95 constexpr std::string_view dbdNameView()
const {
96 return dbdName ? std::string_view{dbdName} : std::string_view{};
102 constexpr std::size_t inlineBytes()
const {
103 if (noninline)
return 0;
127 constexpr std::size_t stringSlots()
const {
128 if (noninline)
return 0;
137 template <
typename T>
139 static constexpr bool Value =
false;
142 template <std::
size_t N>
144 static constexpr bool Value =
true;
145 static constexpr std::size_t Langs = N;
149 template <
typename T>
152 static constexpr std::size_t
Extent = 1;
153 static constexpr bool IsArray =
false;
156 template <
typename T, std::
size_t N>
157 struct ElementTraits<std::array<T, N>> {
159 static constexpr std::size_t
Extent = N;
160 static constexpr bool IsArray =
true;
166 inline bool allZero(std::span<const std::byte> bytes) {
167 return std::ranges::all_of(bytes, [](std::byte b) {
168 return b == std::byte{0};
176 template <
typename Spec, std::meta::info M>
178 auto anns = std::meta::annotations_of_with_type(M, ^^Spec);
179 if (anns.empty())
return std::nullopt;
180 return std::meta::extract<Spec>(anns[0]);
187 template <
typename Member>
195 col.
localeCount =
static_cast<std::uint8_t
>(LocstringTraits<Member>::Langs);
197 else if constexpr (std::same_as<Elem, std::string>) {
201 else if constexpr (std::same_as<Elem, float>) {
205 else if constexpr (std::integral<Elem> && !std::same_as<Elem, bool>) {
207 col.
bits =
static_cast<std::uint8_t
>(
sizeof(Elem) * 8);
208 col.
isSigned = std::is_signed_v<Elem>;
210 else static_assert(
false,
"unsupported record column type");
218 template <
typename Record>
220 std::vector<std::meta::info> out;
221 for (
auto m : std::meta::nonstatic_data_members_of(^^Record, std::meta::access_context::unchecked())) out.
223 return std::define_static_array(out);
231 template <
typename Record>
233 std::vector<Column> cols;
235 template for (
constexpr auto m : Members) {
236 using M = [:std::meta::type_of(m):];
238 col.name = std::define_static_string(std::meta::identifier_of(m));
244 return std::define_static_array(cols);
250 template <
typename Record>
252 std::size_t bytes = 0;
261 template <
typename Record>
263 std::uint32_t slots = 0;
272 template <
typename Record>
274 std::size_t slots = 0;
281 template <
typename R>
concept TableRecord = std::is_class_v<R> && std::default_initializable<R> &&
requires {
282 { R::Version } -> std::convertible_to<ClientVersion>; { std::string_view{R::TableName} };
Client version identity, the flavor axis that separates a client's CONTENT version from the engine ge...
A type the table engine can carry as its record: a flat generated (or hand-written test) struct namin...
The column annotation vocabulary generated client-database record structs declare their schema roles ...
LocString — the decoded form of a pre-Cataclysm localized string column (wowdev.wiki "langstringref")...
consteval auto recordMembers()
The reflected non-static data members of record Record, declaration order.
bool allZero(std::span< const std::byte > bytes)
Whether every byte of bytes is zero (an empty span counts as zero).
consteval std::optional< Spec > annotation()
The first annotation of type Spec on reflected member M, if any.
consteval Column classifyMember()
The physical column shape of a record member of type Member — the name and the annotation-carried rol...
consteval std::size_t recordStride()
The fixed record stride of Record inside a WDBC/WDB2 record block.
ColumnType
The logical value class of a column.
@ Int
An integer column; Column::bits / Column::isSigned give the shape.
@ Float
A 32-bit IEEE float column.
@ String
A string-block reference column (u32 offset on disk).
@ LocString
A pre-Cataclysm localized string column (see LocString).
consteval std::uint32_t fieldSlotCount()
The expanded on-disk field slot count of Record (the WDBC/WDB2 header fieldCount a fresh write derive...
consteval auto schemaOf()
The column schema of record Record, derived by reflection: one Column per member, declaration order,...
consteval std::size_t stringSlotCount()
The string-block references one record of Record stores — the width of the engine's per-record origin...
One column of a record schema, derived from a record member by reflection (typed records) or from the...
const char * dbdName
The verbatim WoWDBDefs spelling of the column ('MapName_lang'); column_index accepts it as an alias.
constexpr std::string_view nameView() const
The member spelling as a view.
constexpr std::string_view dbdNameView() const
The verbatim WoWDBDefs spelling as a view.
bool noninline
Whether the column holds no bytes inside the record image ($noninline$).
constexpr std::size_t inlineBytes() const
The bytes the column occupies inside a fixed-stride (WDBC/WDB2) record image: zero when noninline,...
std::uint8_t localeCount
LocString language slots (8 or 16); 0 otherwise.
bool isId
Whether this is the table's primary key ($id$).
const char * name
The column name: the snake_case spelling of the WoWDBDefs column ('MapName' -> 'map_name').
std::uint16_t arrayLen
Element count; 1 for scalar columns.
ColumnType type
The logical value class.
bool isRelation
Whether this is a relationship key ($relation$).
constexpr std::size_t stringSlots() const
The string-block references the column stores per record (the width of the engine's per-record offset...
constexpr std::uint32_t fieldSlots() const
The expanded on-disk field slots the column contributes to a WDBC/WDB2 header field count: arrays cou...
Column()=default
User-declared (defaulted) so Column is NOT an aggregate: bindings would otherwise synthesize a field-...
std::uint8_t bits
Integer element width in bits; 32 for float/string refs.
bool isSigned
Integer signedness; false for non-Int columns.
A decoded pre-Cataclysm localized string column: Langs language slots (8 before TBC 2....
static constexpr bool IsArray
static constexpr std::size_t Extent
Trait: the element type / extent of a member — unwraps std::array.
static constexpr bool IsArray
static constexpr std::size_t Extent
static constexpr bool Value
static constexpr std::size_t Langs
Trait: is T a LocString<N>?
static constexpr bool Value