Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into package
Browse files Browse the repository at this point in the history
  • Loading branch information
maggu2810 committed Jan 8, 2024
2 parents 6cd0f17 + e1d68f5 commit 4acadba
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 51 deletions.
2 changes: 1 addition & 1 deletion common/include/cpp-valptridx.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class untyped_utilities
class allow_end_construction {};
class allow_none_construction {};
class assume_nothrow_index {};
class rebind_policy;
class rebind_policy {};
};

/* Map the four reporting styles from their `literal_as_type`
Expand Down
15 changes: 7 additions & 8 deletions common/include/valptridx.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ class valptridx<managed_type>::ptr :
}

ptr(std::nullptr_t)
requires(allow_nullptr) // This constructor always stores nullptr, so require a policy with `allow_nullptr == true`.
requires(policy::allow_nullptr) // This constructor always stores nullptr, so require a policy with `allow_nullptr == true`.
:
m_ptr(nullptr)
{
Expand Down Expand Up @@ -616,7 +616,7 @@ class valptridx<managed_type>::ptr :
* This serves as a basic check against casts that could remove
* `const` incorrectly.
*/
return ptr(std::move(rhs), static_cast<const typename containing_type::rebind_policy *>(nullptr));
return ptr(std::move(rhs), typename containing_type::rebind_policy{});
}
pointer_type operator->() const &
{
Expand Down Expand Up @@ -692,18 +692,17 @@ class valptridx<managed_type>::ptr :
}
ptr(allow_none_construction)
requires(
!allow_nullptr // allow_none_construction is only needed where nullptr is not already legal
!policy::allow_nullptr // allow_none_construction is only needed where nullptr is not already legal
)
:
m_ptr(nullptr)
{
}
template <typename rpolicy>
ptr(ptr<rpolicy> &&rhs, const typename containing_type::rebind_policy *)
requires(
allow_nullptr || !rhs.allow_nullptr // cannot rebind from allow_invalid to require_valid
policy::allow_nullptr || !ptr<rpolicy>::allow_nullptr // cannot rebind from allow_invalid to require_valid
)
:
ptr(ptr<rpolicy> &&rhs, typename containing_type::rebind_policy) :
m_ptr{const_cast<managed_type *>(rhs.get_unchecked_pointer())}
{
}
Expand Down Expand Up @@ -834,7 +833,7 @@ class valptridx<managed_type>::ptridx :
requires(!std::is_same<policy, rpolicy>::value)
ptridx rebind_policy(ptridx<rpolicy> &&rhs) const
{
return ptridx(std::move(rhs), static_cast<const typename containing_type::rebind_policy *>(nullptr));
return ptridx(std::move(rhs), typename containing_type::rebind_policy{});
}
ptridx absolute_sibling(const index_type i DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_L_DECL_VARS) const
{
Expand Down Expand Up @@ -863,7 +862,7 @@ class valptridx<managed_type>::ptridx :
return *this;
}
template <typename rpolicy>
ptridx(ptridx<rpolicy> &&rhs, const typename containing_type::rebind_policy *const rebind) :
ptridx(ptridx<rpolicy> &&rhs, const typename containing_type::rebind_policy rebind) :
vptr_type{static_cast<typename ptridx<rpolicy>::vptr_type &&>(rhs), rebind},
vidx_type{static_cast<typename ptridx<rpolicy>::vidx_type &&>(rhs)}
{
Expand Down
37 changes: 24 additions & 13 deletions similar/main/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2332,21 +2332,32 @@ window_event_result browser::callback_handler(const d_event &event, window_event
return get_absolute_path(userdata, "");
else
{
const size_t len_newpath = strlen(newpath.data());
const size_t len_item = strlen(list[citem]);
/* The separator may or may not be included, depending on
* whether one is already present. Regardless of whether a new
* separator is printed by the block, require sufficient space
* for it to fit. This is pessimistic, but should discourage
* gcc's -Wformat-truncation from warning about insufficient
* buffer capacity. In practice, users should never have a
* path that approaches this limit, so the `if` test should
* succeed in all reasonable cases.
const std::size_t len_newpath{strlen(newpath.data())};
const std::size_t len_item{1 + strlen(list[citem])}; // also copy the trailing null
const std::size_t len_sep{strlen(sep)};
/* If `newpath` is long enough to contain a separator, test
* whether it ends with a separator. If it is not long enough
* to contain one, or is tested and does not end with one, then
* set `len_copy_sep` to copy from `sep`. Otherwise, set
* `len_copy_sep` to copy nothing.
*/
const size_t len_sep = strlen(sep);
if (len_newpath + len_item + len_sep < newpath.size())
const std::size_t len_copy_sep{
(len_newpath >= len_sep && !memcmp(&newpath[len_newpath - len_sep], sep, len_sep))
? std::size_t{0}
: len_sep
};
const std::size_t capacity_newpath{newpath.size()};
/* In practice, users should never have a path that approaches
* this limit, so the `if` test should succeed in all
* reasonable cases.
*/
if (const std::size_t total_used_after_insertion{len_newpath + len_copy_sep + len_item}; total_used_after_insertion < capacity_newpath)
{
snprintf(&newpath[len_newpath], newpath.size() - len_newpath, "%s%s", (len_newpath >= len_sep && strncmp(&newpath[len_newpath - len_sep], sep, len_sep)) ? sep : "", list[citem]);
const auto begin_insert_sep{std::next(newpath.begin(), len_newpath)};
const auto begin_insert_item{std::ranges::copy_n(sep, len_copy_sep, begin_insert_sep).out};
const auto end_insert_item{std::ranges::copy_n(list[citem], len_item, begin_insert_item).out};
(void)end_insert_item;
assert(end_insert_item == std::next(newpath.begin(), total_used_after_insertion));
}
}
if ((citem == 0) || PHYSFS_isDirectory(list[citem]))
Expand Down
74 changes: 45 additions & 29 deletions similar/main/multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,40 +722,56 @@ namespace dsx {
void multi_sort_kill_list()
{
auto &Objects = LevelUniqueObjectState.Objects;
auto &vcobjptr = Objects.vcptr;
// Sort the kills list each time a new kill is added
per_player_array<int> kills;
for (playernum_t i = 0; i < MAX_PLAYERS; ++i)
{
auto &player_info = vcobjptr(vcplayerptr(i)->objnum)->ctype.player_info;
if (Game_mode & GM_MULTI_COOP)
{
kills[i] = player_info.mission.score;
}
const auto build_kill_list_sort_key{[](fvcobjptr &vcobjptr, const game_mode_flags game_mode,
#if defined(DXX_BUILD_DESCENT_II)
else
if (Show_kill_list == show_kill_list_mode::efficiency)
const show_kill_list_mode show_kill_list,
#endif
const player &plr) -> int {
const auto o{plr.objnum};
if (o == object_none)
return -1;
auto &player_info = vcobjptr(o)->ctype.player_info;
if (game_mode & GM_MULTI_COOP)
return {player_info.mission.score};
const auto net_kills_total{player_info.net_kills_total};
#if defined(DXX_BUILD_DESCENT_II)
if (show_kill_list == show_kill_list_mode::efficiency)
{
const auto kk = player_info.net_killed_total + player_info.net_kills_total;
// always draw the ones without any ratio last
kills[i] = kk <= 0
? kk - 1
: static_cast<int>(
static_cast<float>(player_info.net_kills_total) / (
static_cast<float>(player_info.net_killed_total) + static_cast<float>(player_info.net_kills_total)
) * 100.0
);
const auto kk{player_info.net_killed_total + net_kills_total};
if (kk <= 0)
// always draw the ones without any ratio last
return kk - 1;
const float net_kills_total_f = net_kills_total;
return static_cast<int>(net_kills_total_f / (
static_cast<float>(player_info.net_killed_total) + net_kills_total_f
) * 100.0f);
}
#endif
else
kills[i] = player_info.net_kills_total;
}

const auto predicate = [&](unsigned a, unsigned b) {
return kills[a] > kills[b];
};
const auto &range = partial_range(sorted_kills, N_players);
std::sort(range.begin(), range.end(), predicate);
return {net_kills_total};
}};
const auto build_kill_list_sort_keys{[build_kill_list_sort_key](fvcobjptr &vcobjptr, const game_mode_flags game_mode,
#if defined(DXX_BUILD_DESCENT_II)
const show_kill_list_mode show_kill_list,
#endif
fvcplayerptr &vcplayerptr) -> per_player_array<int> {
per_player_array<int> kills;
for (auto &&[k, plr] : zip(kills, vcplayerptr))
k = build_kill_list_sort_key(vcobjptr, game_mode,
#if defined(DXX_BUILD_DESCENT_II)
show_kill_list,
#endif
plr);
return kills;
}};
const auto projection{[keys = build_kill_list_sort_keys(Objects.vcptr, Game_mode,
#if defined(DXX_BUILD_DESCENT_II)
Show_kill_list,
#endif
vcplayerptr)](const unsigned sk) {
return keys[sk];
}};
std::ranges::sort(partial_range(sorted_kills, N_players), std::ranges::greater{}, std::ref(projection));
}

namespace {
Expand Down

0 comments on commit 4acadba

Please sign in to comment.