12#include <unordered_set>
37 return "defines-only";
43 panic(
"unhandled HeaderFormat value");
76 panic(
"unhandled FieldRole value");
90 if (text ==
"layer_type") {
154struct EnumDefinition;
229 std::optional<ProviderDefinition>
provider = std::nullopt,
230 std::optional<FieldRole>
role = std::nullopt)
236 [[nodiscard]]
const std::string &
name()
const
241 [[nodiscard]] std::uint32_t
mask()
const
248 return default_value_;
255 [[nodiscard]] std::uint32_t
offset()
const
257 return static_cast<std::uint32_t
>(std::countr_zero(mask_));
263 [[nodiscard]] std::uint32_t
width()
const
265 return static_cast<std::uint32_t
>(std::popcount(mask_));
283 return provider_.has_value();
286 [[nodiscard]]
const std::optional<FieldRole> &
role()
const
310 assert_or_panic(provider_.has_value(),
"Field::provider_definition() called on a field with no provider");
311 return provider_.value();
317 std::uint32_t default_value_;
318 std::optional<ProviderDefinition> provider_;
319 std::optional<FieldRole> role_;
353 [[nodiscard]]
const std::vector<Field> &
fields()
const
370 return value_fields_;
375 return attribute_bytes_;
383 return layer_type_index_.has_value() ? &fields_[layer_type_index_.value()] :
nullptr;
396 return layer_type_mask_;
408 return static_cast<std::uint32_t
>(std::countr_zero(layer_type_mask_));
413 : fields_{std::move(
fields)}, attribute_bytes_{
attribute_bytes}, layer_type_index_{layer_type_index},
414 layer_type_mask_{layer_type_index.has_value() ? fields_[layer_type_index.value()].mask() : 0}
416 for (
const Field &field : fields_) {
417 if (!field.packs_layer_type()) {
418 value_fields_.push_back(field);
423 std::vector<Field> fields_;
426 std::vector<Field> value_fields_;
427 std::size_t attribute_bytes_;
429 std::optional<std::size_t> layer_type_index_;
430 std::uint32_t layer_type_mask_;
437 constexpr auto parse(std::format_parse_context &ctx)
450 constexpr auto parse(std::format_parse_context &ctx)
A result type that maintains a chainable sequence of errors for debugging and error reporting.
One named bit-field within a metatile attribute layout.
const ProviderDefinition & provider_definition() const
Returns the field's provider definition.
const std::string & name() const
std::uint32_t offset() const
Returns the bit offset of the field's least-significant bit.
std::uint32_t default_value() const
bool packs_layer_type() const
Reports whether this field carries the layer_type role.
const std::optional< FieldRole > & role() const
std::uint32_t width() const
Returns the number of bits the field occupies.
bool has_provider() const
Field(std::string name, std::uint32_t mask, std::uint32_t default_value=0, std::optional< ProviderDefinition > provider=std::nullopt, std::optional< FieldRole > role=std::nullopt)
Constructs a field from a name, mask, and optional default value, provider definition,...
std::uint32_t mask() const
std::uint32_t max_value() const
Returns the largest value the field can hold.
A validated metatile attribute layout: an ordered set of non-overlapping fields.
std::uint32_t layer_type_offset() const
Returns the bit offset of the layer_type's least-significant bit.
static ChainableResult< Schema > create(std::vector< Field > fields, std::size_t attribute_bytes)
Validates a set of fields against an attribute size and builds a Schema.
const std::vector< Field > & value_fields() const
Returns the fields that hold plain per-metatile values, excluding the layer_type-role field.
std::uint32_t layer_type_mask() const
Returns the mask of the layer_type bits within the packed attribute word.
const Field * layer_type_field() const
Returns the field carrying the layer_type role, or nullptr when the layer type is disabled.
const std::vector< Field > & fields() const
std::size_t attribute_bytes() const
std::string pin_column_name(FieldRole role)
Returns the one legal attributes.csv column name for a role's pin column.
bool is_pin_column_name(const std::string &name)
Reports whether a column name sits in the reserved pin namespace.
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
void assert_or_panic(bool condition, const StringViewSourceLoc &s)
Conditionally panics if the given condition is false.
std::ostream & operator<<(std::ostream &os, const PrimaryPairingMode m)
Stream insertion operator for PrimaryPairingMode.
constexpr std::string_view pin_column_prefix
The reserved prefix marking an attributes.csv header column as a role pin column.
HeaderFormat
Describes which header declaration styles a provider header may use.
std::optional< FieldRole > field_role_from_string(const std::string &text)
Parses a FieldRole from its string form, or nullopt when the name is not a known role.
FieldRole
Semantic roles a schema field can carry beyond holding a plain per-metatile value.
std::optional< FieldRole > role_from_pin_column_name(const std::string &name)
Parses the role out of a pin column name.
std::string to_string(const PrimaryPairingMode m)
Converts a PrimaryPairingMode to its canonical string representation.
The self-contained description a header enum provider needs to scan and validate values.
std::string field_display_name
bool operator==(const EnumDefinition &) const =default
std::unordered_set< std::string > skipped
Describes where and how a field's named values are declared.
std::unordered_set< std::string > skipped
EnumDefinition to_enum_definition(std::string field_display_name, std::uint32_t max_value) const
Builds the resolvable enum definition a header provider needs from this description.
bool operator==(const ProviderDefinition &) const =default
std::filesystem::path header