Adjust code_window_point to use the same masks as clipping_code.
Previously, it had top and bottom swapped. However, since its output
was only ever compared for equality to 0, this transposition should not
affect the observable behavior.
gcc libstdc++ built with -D_GLIBCXX_DEBUG includes in
std::array::operator[] an assertion of the form:
```
assert(index < size());
```
The valptridx allow_end_construction constructor, when given a
completely full array, will call operator[](size()), which causes the
assertion to fail. Rework the constructor to compute an end iterator
without using operator[]. valptridx allow_end_construction expects that
the resulting iterator may be the end iterator and shall not be
dereferenced.
Introduce a helper to obtain both the magnitude of a vector and the
corresponding normalized vector. Use it to capture both values as const
when possible.
clang-14 is detected as being able to optimize out unreachable paths,
but then triggers a build error reporting an unspecified invalid use
somewhere in multi.cpp.
Remove the static check, and rely on -Wsuggest-attribute=noreturn to
report any functions which are guaranteed to fail. This is a weaker
check, but over the course of development, the static check has been hit
rarely, if ever, so keeping it provides little value.
```
In file included from similar/main/multi.cpp:38:
In file included from common/main/game.h:32:
In file included from common/main/robot.h:34:
In file included from common/main/object.h:40:
common/include/valptridx.h:229:2: error: call to unsigned int valptridx<dcx::player>::check_index_range_size<valptridx<dcx::player>::index_range_exception, std::__1::less>(char const*, unsigned int, unsigned long, valptridx<dcx::player>::array_managed_type const*)::DXX_ALWAYS_ERROR_FUNCTION::dxx_trap_handle_index_range_error() declared with 'error' attribute: invalid index used in array subscript
DXX_VALPTRIDX_CHECK(Compare<std::size_t>()(s, array_size), handle_index_range_error, "invalid index used in array subscript", a, s);
^
common/include/valptridx.h:37:3: note: expanded from macro 'DXX_VALPTRIDX_CHECK'
DXX_VALPTRIDX_STATIC_CHECK(dxx_valptridx_check_success_condition, dxx_trap_##ERROR, FAILURE_STRING); \
^
common/include/valptridx.h:20:5: note: expanded from macro 'DXX_VALPTRIDX_STATIC_CHECK'
(DXX_ALWAYS_ERROR_FUNCTION(FAILURE_FUNCTION, FAILURE_STRING), 0) \
^
build/ulinux-clang++-14-64b10d04-ogl/dxxsconf.h:84:2: note: expanded from macro 'DXX_ALWAYS_ERROR_FUNCTION'
DXX_ALWAYS_ERROR_FUNCTION::F(); \
^
1 error generated.
```
Compiler error messages are generally better when reporting a misuse
that fails a requires() versus reporting a misuse that fails a
std::enable_if. In some cases, this also makes the code clearer, and
avoids the need for dummy template parameters as a place to invoke
std::enable_if.
clang-13 needed an operator==(const exact_type<T>&) defined to avoid an
ambiguity. Now that C++20 mode is enabled, switch to a
compiler-generated operator== instead of manually defining the
equivalent function.
In C++ 20 mode, clang-13 gets confused about how to handle operator==.
Rewrite the test to encourage it to pick the correct version.
```
common/include/gr.h:129:12: error: use of overloaded operator '==' is ambiguous (with operand types 'dcx::grs_main_bitmap *' and 'exact_type<dcx::grs_bitmap>')
if (this == &r)
~~~~ ^ ~~
common/include/pack.h:31:17: note: candidate function (with reversed parameter order)
constexpr bool operator==(const T *rhs) const { return p == rhs; }
^
common/include/gr.h:129:12: note: built-in candidate operator==(struct dcx::grs_bitmap *, struct dcx::grs_bitmap *)
if (this == &r)
```
clang-13 in C++20 mode fails:
```
similar/main/newmenu.cpp:202:18: error: ISO C++20 considers use of overloaded operator '==' (with operand types 'exact_type<const dcx::grs_font>' and 'exact_
type<const dcx::grs_font>') to be ambiguous despite there being a unique best viable function [-Werror,-Wambiguous-reversed-operator]
return &cv_font == &game_font ? "\202" : "\207"; // 135
~~~~~~~~ ^ ~~~~~~~~~~
common/include/pack.h:31:17: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
constexpr bool operator==(const T *rhs) const { return p == rhs; }
^
```
Add an operator== that exactly matches the input types so that clang
does not attempt a conversion.
This produces a better error message than a static_assert failure, since
gcc points directly to the call which resolved to the deleted overload.
When the caller is correct, this produces the same result as the prior
version.
splitpath_t is designed for MS-DOS paths, even though Rebirth now runs
on many platforms that never used DOS conventions. Most of the members
of splitpath_t are unused on all platforms. Remove them, and switch to
returning an initialized version of the structure.
Previously, the supplied pointer was converted to an array index, then
passed to valptridx::idx for validation. If the index_type is smaller
than std::size_t, this would truncate the value before validation.
Certain out-of-range indexes would be in-range after truncation, and
incorrectly not be reported.
Reorder the check to validate the index against the array size before
truncation.
The type aliases are sufficient. Individual bytebuffer_t
implementations can define a `static constexpr` member `endian` from the
type alias and rely on `std::integral_constant<T, V>::operator()`
instead of defining a `static` method just to return an instance of the
`std::integral_constant`.
This allows taking the input by-value instead of by-reference, while
still protecting against unwanted type conversion.
Add some basic static_assert tests that the swapped values are correct.
Commit f1606f7747 ("Simplify test for
__builtin_bswap16") changed the SConstruct test to either define both
DXX_HAVE_BUILTIN_BSWAP and DXX_HAVE_BUILTIN_BSWAP16 or to define neither
of them. Follow up that commit by removing the definition of
DXX_HAVE_BUILTIN_BSWAP16 and redirecting uses of it to
DXX_HAVE_BUILTIN_BSWAP.
Split check_index_range to check_index_range+check_index_range_size.
Redirect check_explicit_index_range_ref to check_index_range_size, so
that the index_type is not truncated and then extended.
The contents of the output buffer are undefined if PHYSFSX_getRealPath
fails, so mark the function as [[nodiscard]] and modify all callers to
check that the function succeeded.
Rework the error paths to return path-specific status codes so that the
caller can report exactly which step caused an HMP file to be rejected.
On error, print this reason numerically and, if the reason was a PhysFS
error, also print the PhysFS error code numerically and symbolically.
If two or more events are delivered in the same loop, the previous
implementation would count joystick motion multiple times. Fix this by
moving the joystick interpretation to occur once, after all the events
have been processed.
Instead of creating the powerup from a player, then overwriting the
location and velocity of the powerup, and fixing up its segment, create
the powerup directly where it should be, with the intended velocity.
Most callers do not need it, and it is only vaguely related to the
purpose of measuring a particular string. For those callers that need
it, lift it out.
Some targets only ever use GUI warn functions. On those targets:
- initialize `warn_func` to `msgbox_warning` at compile time
- remove the runtime initialize of warn_func in main
On targets which do not call `clear_warn_func`, preprocess out its
declaration and definition.
Taken together, these changes allow some targets not to define
`warn_printf`.
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.
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 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.