3#include <tess/storage/chunk_page.h>
18namespace tess::movement {
29template <
typename Tag>
31 template <
typename Page>
32 [[nodiscard]]
static constexpr bool eval(
const Page& page,
34 static_assert(Page::schema_type::template contains<Tag>,
35 "MovementClass references a field absent from the schema.");
36 return static_cast<bool>(page.template field<Tag>(
id));
42template <
typename Tag>
44 template <
typename Page>
45 [[nodiscard]]
static constexpr bool eval(
const Page& page,
47 static_assert(Page::schema_type::template contains<Tag>,
48 "MovementClass references a field absent from the schema.");
49 return page.template field<Tag>(
id) != 0;
54template <
typename Term>
56 template <
typename Page>
57 [[nodiscard]]
static constexpr bool eval(
const Page& page,
59 return !Term::eval(page,
id);
64template <
typename... Terms>
66 template <
typename Page>
67 [[nodiscard]]
static constexpr bool eval(
const Page& page,
69 return (
true && ... && Terms::eval(page,
id));
74template <
typename... Terms>
76 template <
typename Page>
77 [[nodiscard]]
static constexpr bool eval(
const Page& page,
79 return (
false || ... || Terms::eval(page,
id));
93template <
typename Value>
94[[nodiscard]]
constexpr std::uint32_t normalize_cost(Value value)
noexcept {
95 static_assert(std::is_integral_v<std::remove_cvref_t<Value>>,
96 "MovementClass cost field must be integral.");
97 if constexpr (std::is_signed_v<std::remove_cvref_t<Value>>) {
101 }
else if (value == 0) {
104 if (
static_cast<std::uint64_t
>(value) >
105 std::numeric_limits<std::uint32_t>::max()) {
106 return std::numeric_limits<std::uint32_t>::max();
108 return static_cast<std::uint32_t
>(value);
115 template <
typename Page>
116 [[nodiscard]]
static constexpr std::uint32_t eval(
const Page&,
123template <std::u
int32_t N>
125 template <
typename Page>
126 [[nodiscard]]
static constexpr std::uint32_t eval(
const Page&,
133template <
typename CostTag>
135 template <
typename Page>
136 [[nodiscard]]
static constexpr std::uint32_t eval(
const Page& page,
138 static_assert(Page::schema_type::template contains<CostTag>,
139 "MovementClass references a field absent from the schema.");
140 return normalize_cost(page.template field<CostTag>(
id));
147template <
typename SelTag,
typename WhenSet,
typename WhenClear>
149 template <
typename Page>
150 [[nodiscard]]
static constexpr std::uint32_t eval(
const Page& page,
152 static_assert(Page::schema_type::template contains<SelTag>,
153 "MovementClass references a field absent from the schema.");
154 return static_cast<bool>(page.template field<SelTag>(
id))
155 ? WhenSet::eval(page,
id)
156 : WhenClear::eval(page,
id);
163template <
typename PassExpr,
typename CostExpr>
165 using pass_expr = PassExpr;
166 using cost_expr = CostExpr;
168 template <
typename Page>
169 [[nodiscard]]
static constexpr bool passable(
const Page& page,
171 return PassExpr::eval(page,
id);
174 template <
typename Page>
175 [[nodiscard]]
static constexpr std::uint32_t entry_cost(
177 return CostExpr::eval(page,
id);
183template <
typename C,
typename Page>
187 C::passable(page,
id)
188 } -> std::convertible_to<bool>;
190 C::entry_cost(page,
id)
191 } -> std::convertible_to<std::uint32_t>;
201template <
typename PassableTag>
203 using passable_tag = PassableTag;
205 template <
typename Page>
206 [[nodiscard]]
static constexpr auto passable_span(Page& page)
noexcept {
207 return page.template field_span<PassableTag>();
216template <
typename PassableTag,
typename CostTag>
219 FieldCost<CostTag>> {};
225template <
typename PassableTag,
typename CostTag>
243using movement_class_of =
244 std::conditional_t<std::derived_from<T, movement_class_tag>, T,
Checks whether a movement class advertises the exact field-span fast path.
Definition movement_class.h:236
Checks that C provides movement operations compatible with Page.
Definition movement_class.h:184
Requires every supplied passability term to evaluate true.
Definition movement_class.h:65
Requires at least one supplied passability term to evaluate true.
Definition movement_class.h:75
Produces compile-time constant entry cost N for every tile.
Definition movement_class.h:124
Reads and normalizes integral entry cost field CostTag.
Definition movement_class.h:134
Evaluates the truthiness of field Tag at a resolved tile.
Definition movement_class.h:30
Combines compile-time passability and entry-cost expressions.
Definition movement_class.h:164
Evaluates whether integral field Tag is nonzero at a resolved tile.
Definition movement_class.h:43
Negates one compile-time passability term.
Definition movement_class.h:55
Selects between two cost expressions using field SelTag.
Definition movement_class.h:148
Produces unit entry cost for every tile.
Definition movement_class.h:114
Combines a truthy field and positive cost field into weighted movement.
Definition movement_class.h:219
Adapts a truthy passability field to unit-cost movement.
Definition movement_class.h:202
Marks types that implement the compile-time movement-class contract.
Definition movement_class.h:23