1024 is excessive. 128 leaves 25 bytes unused on Trainee (the longest
difficulty string, tied with Hotshot) at time 0:00:00. A player who
reached double-digit hours for both time on level and time in game would
need 2 bytes more. A player who rescued 100 hostages would need another
2 bytes.
The existing code checks that w.m_ptr is not nullptr before using it.
clang's flow analysis is unable to prove that w.m_ptr does not become
nullptr after it was first checked, even though `w` is const. This
causes clang to include calls to null_pointer_exception::report, which
is not instantiated for wall. That in turn causes a link error.
Rewrite the code to let clang see that the value tested is the value
used, and that no nullptr dereference can happen here.
When partial_range is used on a container that defines index_type,
define that same index_type on the partial_range. This allows other
callers, such as enumerate(), to maintain the correct index type.
All the affected symbols are templates, so duplicate instantiations will
not cause duplicate definition errors. Removing the anonymous namespace
wrapper will allow equivalent definitions from different source files to
be folded together, reducing the size of the executable.
Push the computation up, so that invocations that differ only in the
length of their expression strings will resolve to the same template.
Rework unchecked_partial_range not to take expression strings if they
will not be used.
- UO -> index_begin_type
- o -> index_begin
- UL -> index_end_type
- l -> index_end
- I -> range_exception
The original names were picked because `l` was the length of the
subrange. Rename these to more closely follow STL's begin/end
nomenclature.
`I` was used variously for an iterator type and for the exception type
thrown on error. Rename the latter to be descriptive.
- Inline add_computed_color into gr_find_closest_color, and then only
one function will need access to Computed_colors.
- Allow the recent-choice bubble-up logic to apply to all elements
- If all entries are in use, always overwrite the last element in
Computed_colors instead of picking one randomly.
gr_find_closest_color did not need it. Remove it. For the others,
resetting the count is sufficient. There is no need to reset the
individual elements.
- Add a limiter to let it return early when the result is predictable.
The first caller checks only whether the returned value is above a
threshold. Once the value goes above that threshold, its precise
value will not matter, so stop counting and return early.
- Add comments explaining some of the logic.
Add a helper to deduce the enum type of a value, and use an appropriate
std::underlying_type<T> expression for that enum type. This avoids the
need to repeat the type of the enum at the site of each cast, and moves
the casts into the helper to make the callers easier to read.
- Use std::iota to initialize the translation array
- Switch from conditionally using either a linear count or the array to
always using the array. In non-random mode, the array is initialized
and never shuffled, so it should produce the same effect as using the
linear count, but avoids a branch in the loop.
- Switch to using std::shuffle driven by std::minstd_rand, rather than
an inline swap loop using d_rand() to pick indices.
- Reorder the shuffle logic to have exactly one invocation in each game,
so that the shuffle call itself can be eligible for inlining.
- Use std::uniform_int_distribution to decide whether to reshuffle in
Descent 2. Maintain the original logic that reshuffling happens 25%
of the time.
In gcc-7, expressions on the false path of `if constexpr` are deleted
before they are considered "used", so a variable that is only used on a
deleted path is reported as an unused variable. Add an alternate path
that casts the variable to void so that it is always used.