Source code for ifgen.struct.methods.fields.setter
"""
A module implementing 'set' methods for bit-fields.
"""
# built-in
from typing import Any, Iterator
# third-party
from vcorelib.io.file_writer import IndentedFileWriter
# internal
from ifgen.generation.interface import GenerateTask
from ifgen.struct.methods.bit import (
bit_field_toggle_method,
handle_description,
)
from ifgen.struct.methods.fields.common import (
BitField,
bit_field_method_slug,
bit_field_underlying,
bit_mask_literal,
possible_array_arg,
)
[docs]
def bit_field_set_all_method(
task: GenerateTask,
writer: IndentedFileWriter,
header: bool,
field: dict[str, Any],
fields: list[BitField],
alias: str = None,
) -> None:
"""Generate a 'set' method for multiple bit-field."""
if not header:
return
name = field["name"] if not alias else alias
inner = possible_array_arg(field)
if inner:
inner += ", "
with writer.javadoc():
writer.write(f"Set all of {name}'s bit fields.")
handle_description(writer, field)
# Add field args.
args = []
for bit_field in fields:
args.append(f"{bit_field_underlying(bit_field)} {bit_field['name']}")
inner += ", ".join(args)
writer.write(f"inline void set_{name}({inner}){task.method_suffix()}")
with writer.scope():
rhs = field["name"] if not alias else alias
if "index" in inner:
rhs += "[index]"
writer.write(f"{field['type']} curr = {rhs};")
with writer.padding():
for bit_field in fields:
for line in bit_field_set_lines(
task, bit_field, value=bit_field["name"]
):
writer.write(line)
writer.write(f"{rhs} = curr;")
[docs]
def bit_field_set_lines(
task: GenerateTask,
field: BitField,
lhs: str = "curr",
value: str = "value",
) -> Iterator[str]:
"""Get lines that perform a bit-field's assignment."""
mask = bit_mask_literal(field["width"])
yield f"{lhs} &= ~({mask} << {field['index']}u);"
val_str = value
if task.env.is_enum(bit_field_underlying(field)):
val_str = f"std::to_underlying({val_str})"
yield f"{lhs} |= ({val_str} & {mask}) << {field['index']}u;"
[docs]
def bit_field_set_method(
task: GenerateTask,
parent: dict[str, Any],
field: BitField,
writer: IndentedFileWriter,
header: bool,
alias: str = None,
) -> None:
"""Generate a 'set' method for a bit-field."""
method_slug = bit_field_method_slug(parent, field["name"], alias=alias)
kind = bit_field_underlying(field)
# Generate a toggle method for bit fields.
if field["width"] == 1:
bit_field_toggle_method(
task, parent["name"], field, writer, header, method_slug
)
else:
if not header:
return
inner = possible_array_arg(parent)
if inner:
inner += ", "
inner += f"{kind} value"
method = task.cpp_namespace(
f"set_{method_slug}({inner}){task.method_suffix()}", header=header
)
writer.empty()
if header:
with writer.javadoc():
writer.write(f"Set {parent['name']}'s {field['name']} field.")
handle_description(writer, field)
writer.write("inline void " + method)
with writer.scope():
rhs = parent["name"] if not alias else alias
if "index" in inner:
rhs += "[index]"
writer.write(f"{parent['type']} curr = {rhs};")
with writer.padding():
for line in bit_field_set_lines(task, field):
writer.write(line)
writer.write(f"{rhs} = curr;")