This is only used in the file where it is defined, so it can be inlined
even though the definition is not in a header. Enabling inlining
encourages gcc to see that the `operator new`/`operator delete` calls
are not mismatched.
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.
```
Given this code:
```
enum class X : unsigned;
X a{1};
```
gdb has an unfortunate behavior of reporting "incomplete type" and
refusing to show the underlying value of `a`, even when `a` is in scope.
Adding `enum class X : unsigned {}` fixes this and allows gdb to show
the value.
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.
The caller has the player object, and can provide the orientation matrix
from it. Use that instead of letting multi_send_fire recompute the
object in order to get the matrix.
When the player fires a generic secondary, the choice of proximity bomb
versus super-mine is never read. When the player specifically drops a
bomb, only that choice needs to be read. Pass the chosen weapon as an
argument, and avoid computing the choice on the path where it is never
read.
Two paths are always local. One path is always remote. Split the
handler function to remove the locality test and rely on the caller's
knowledge of whether the affected player is local.
Instead of sliding the entire queue down one element at a time, move the
non-expired elements in one step, and wipe all the trailing elements
in a single pass.
The only values for any given player are true/false, so use a bitset
instead of a byte per player. Some implementations may use a uint64_t
internally, negating the space savings. Even so, this version is
an improvement for requiring the use of playernum_t as an index.
The function had one caller, which always passed `0`. Inline that.
Next, observe that `sent` is only ever modified `if (!(Game_mode &
GM_NETWORK))`. As a multiplayer function, `multi_send_robot_frame`
should never be called in single-player, so this test should always be
false. Delete it, and observe that `sent` is now `const`.
Remove unused return value of `multi_send_robot_frame`.