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.