Pass std::span to callsign_t::copy

This commit is contained in:
Kp 2022-09-24 17:47:53 +00:00
parent 81b77d2f28
commit 9d238eedf8
3 changed files with 28 additions and 11 deletions

View file

@ -8,10 +8,10 @@
#pragma once
#ifdef __cplusplus
#include <algorithm>
#include <cctype>
#include <cstddef>
#include <span>
#include "dxxsconf.h"
#include <array>
@ -28,10 +28,18 @@ struct callsign_t
{
return std::tolower(static_cast<unsigned>(c));
}
void copy(const char *s, std::size_t N)
template <std::size_t Extent>
requires(Extent == std::dynamic_extent || Extent <= array_length)
void copy(const std::span<const char, Extent> s)
{
/* Zero the entire array first, so that word-sized moves can be used to
* store the null bytes in bulk. Then copy an appropriate number of
* characters using byte-sized moves, with a limit to prevent
* overwriting the final null byte even if the input string is too
* long.
*/
a = {};
std::copy_n(s, std::min(a.size() - 1, N), begin(a));
std::copy_n(s.data(), std::min(a.size() - 1, s.size()), begin(a));
}
void copy_lower(const char *s, std::size_t N)
{
@ -52,8 +60,7 @@ struct callsign_t
template <std::size_t N>
void operator=(const char (&s)[N])
{
static_assert(N <= array_length, "string too long");
copy(s, N);
copy(std::span(s));
}
template <std::size_t N>
void copy_lower(const char (&s)[N])
@ -80,5 +87,3 @@ struct callsign_t
}
};
static_assert(sizeof(callsign_t) == CALLSIGN_LEN + 1, "callsign_t too big");
#endif

View file

@ -726,7 +726,7 @@ static int main(int argc, char *argv[])
}
if(PHYSFSX_exists(filename,0))
{
InterfaceUniqueState.PilotName.copy(b, std::distance(b, &filename[j - 4]));
InterfaceUniqueState.PilotName.copy(std::span<const char>(b, std::distance(b, &filename[j - 4])));
InterfaceUniqueState.update_window_title();
read_player_file();
WriteConfigFile();

View file

@ -204,8 +204,20 @@ net_udp_select_teams_menu_items::net_udp_select_teams_menu_items(const unsigned
blue_team_color(BM_XRGB(player_rgb[0].r, player_rgb[0].g, player_rgb[0].b)),
red_team_color(BM_XRGB(player_rgb[1].r, player_rgb[1].g, player_rgb[1].b))
{
team_names[0].copy(TXT_BLUE, ~0ul);
team_names[1].copy(TXT_RED, ~0ul);
const auto set_team_name = [](callsign_t &team_name, const auto &&s) {
if constexpr (std::is_array<typename std::remove_cvref<decltype(s)>::type>::value)
/* When the input is an array (due to
* -D'USE_BUILTIN_ENGLISH_TEXT_STRINGS'), construct a std::span
* implicitly with the correct length.
*/
team_name.copy(s);
else
/* Otherwise, construct one explicitly with the dynamically
* detected length. */
team_name.copy(std::span(s, strlen(s)));
};
set_team_name(team_names[0], TXT_BLUE);
set_team_name(team_names[1], TXT_RED);
/* Round blue team up. Round red team down. */
const unsigned num_blue_players = (num_players + 1) >> 1;
// Put first half of players on team A
@ -3183,7 +3195,7 @@ static void net_udp_process_game_info_heavy(const uint8_t *data, uint_fast32_t,
Netgame.InvulAppear = data[len]; len += 1;
range_for (auto &i, Netgame.team_name)
{
i.copy(reinterpret_cast<const char *>(&data[len]), (CALLSIGN_LEN+1));
i.copy(std::span<const char, CALLSIGN_LEN + 1>(reinterpret_cast<const char *>(&data[len]), CALLSIGN_LEN + 1));
len += CALLSIGN_LEN + 1;
}
range_for (auto &i, Netgame.locations)