Merge remote-tracking branch 'origin/topic/timw/cpp20-modernization'

* origin/topic/timw/cpp20-modernization:
  Remove intermediate cipher vectors in ssl-analyzer.pac
  Reduce the size of Func::Body quite a bit with some extra packing
  Switch to using std::ranges algorithms
  Enable modernize-std-numbers clang-tidy checker, fix findings
  Switch to using c++20 constraints instead of std::enable_if
This commit is contained in:
Tim Wojtulewicz 2025-07-28 13:12:47 -07:00
commit 020dd1a848
53 changed files with 147 additions and 141 deletions

View file

@ -43,7 +43,6 @@ Checks: [-*,
-modernize-raw-string-literal,
-modernize-use-auto,
-modernize-use-nodiscard,
-modernize-use-ranges,
-modernize-use-trailing-return-type,
-modernize-use-designated-initializers,
@ -64,12 +63,7 @@ Checks: [-*,
# These are features in newer version of C++ that we don't have
# access to yet.
-modernize-use-std-format,
-modernize-use-std-numbers,
-modernize-use-std-print,
# C++20 supports constraints but until Spicy supports building with C++20
# this one has to stay disabled.
-modernize-use-constraints,
]
HeaderFilterRegex: '.h'

12
CHANGES
View file

@ -1,3 +1,15 @@
8.0.0-dev.760 | 2025-07-28 13:12:47 -0700
* Remove intermediate cipher vectors in ssl-analyzer.pac (Tim Wojtulewicz, Corelight)
* Reduce the size of Func::Body quite a bit with some extra packing (Tim Wojtulewicz, Corelight)
* Switch to using std::ranges algorithms (Tim Wojtulewicz, Corelight)
* Enable modernize-std-numbers clang-tidy checker, fix findings (Tim Wojtulewicz, Corelight)
* Switch to using c++20 constraints instead of std::enable_if (Tim Wojtulewicz, Corelight)
8.0.0-dev.754 | 2025-07-28 12:24:41 -0400
* Deprecate `record_type_to_vector` (Evan Typanski, Corelight)

View file

@ -1 +1 @@
8.0.0-dev.754
8.0.0-dev.760

View file

@ -34,6 +34,6 @@ void CCL::Add(int sym) {
syms->push_back(sym_p);
}
void CCL::Sort() { std::sort(syms->begin(), syms->end()); }
void CCL::Sort() { std::ranges::sort(*syms); }
} // namespace zeek::detail

View file

@ -1573,9 +1573,9 @@ TEST_CASE("dns_mgr default mode" * doctest::skip(true)) {
CHECK_FALSE(host_result->EqualTo(TestDNS_Mgr::empty_addr_set()));
auto addrs_from_request = get_result_addresses(host_result);
auto it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones4);
auto it = std::ranges::find(addrs_from_request, ones4);
CHECK(it != addrs_from_request.end());
it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones6);
it = std::ranges::find(addrs_from_request, ones6);
CHECK(it != addrs_from_request.end());
auto addr_result = mgr.LookupAddr(ones4);
@ -1613,7 +1613,7 @@ TEST_CASE("dns_mgr async host" * doctest::skip(true)) {
if ( ! cb.timeout ) {
REQUIRE_FALSE(cb.addr_results.empty());
IPAddr ones("1.1.1.1");
auto it = std::find(cb.addr_results.begin(), cb.addr_results.end(), ones);
auto it = std::ranges::find(cb.addr_results, ones);
CHECK(it != cb.addr_results.end());
}

View file

@ -60,7 +60,7 @@ void DebugLogger::ShowStreamsHelp() {
for ( const auto& stream : streams )
prefixes.emplace_back(stream.prefix);
std::sort(prefixes.begin(), prefixes.end());
std::ranges::sort(prefixes);
for ( const auto& prefix : prefixes )
fprintf(stderr, " %s\n", prefix.c_str());

View file

@ -129,8 +129,8 @@ public:
* A version of Enqueue() taking a variable number of arguments.
*/
template<class... Args>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>> Enqueue(
const EventHandlerPtr& h, Args&&... args) {
requires std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>
void Enqueue(const EventHandlerPtr& h, Args&&... args) {
return Enqueue(h, zeek::Args{std::forward<Args>(args)...});
}

View file

@ -142,7 +142,7 @@ void EventGroup::UpdateFuncBodies() {
func->has_enabled_bodies = false;
func->all_bodies_enabled = true;
for ( auto& b : func->bodies ) {
b.disabled = std::any_of(b.groups.cbegin(), b.groups.cend(), is_group_disabled);
b.disabled = std::ranges::any_of(b.groups, is_group_disabled);
func->has_enabled_bodies |= is_body_enabled(b);
func->all_bodies_enabled &= is_body_enabled(b);
}

View file

@ -293,7 +293,7 @@ ScriptFunc::ScriptFunc(std::string _name, FuncTypePtr ft, std::vector<StmtPtr> b
bodies.push_back(std::move(b));
}
std::stable_sort(bodies.begin(), bodies.end());
std::ranges::stable_sort(bodies, std::ranges::greater(), &Body::priority);
if ( ! bodies.empty() ) {
current_body = bodies[0].stmts;
@ -315,7 +315,7 @@ ScriptFunc::~ScriptFunc() {
}
bool ScriptFunc::IsPure() const {
return std::all_of(bodies.begin(), bodies.end(), [](const Body& b) { return b.stmts->IsPure(); });
return std::ranges::all_of(bodies, [](const Body& b) { return b.stmts->IsPure(); });
}
ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
@ -564,12 +564,12 @@ void ScriptFunc::AddBody(StmtPtr new_body, const std::vector<IDPtr>& new_inits,
Body b;
b.stmts = new_body;
b.groups = groups;
b.groups = {groups.begin(), groups.end()};
current_body = new_body;
current_priority = b.priority = priority;
bodies.push_back(std::move(b));
std::stable_sort(bodies.begin(), bodies.end());
std::ranges::stable_sort(bodies, std::ranges::greater(), &Body::priority);
}
void ScriptFunc::ReplaceBody(const StmtPtr& old_body, StmtPtr new_body) {

View file

@ -2,6 +2,7 @@
#pragma once
#include <forward_list>
#include <memory>
#include <string>
#include <tuple>
@ -66,13 +67,11 @@ public:
struct Body {
detail::StmtPtr stmts;
std::forward_list<EventGroupPtr> groups;
int priority;
std::set<EventGroupPtr> groups;
// If any of the groups are disabled, this body is disabled.
// The disabled field is updated from EventGroup instances.
bool disabled = false;
bool operator<(const Body& other) const { return priority > other.priority; } // reverse sort
};
const std::vector<Body>& GetBodies() const { return bodies; }
@ -104,8 +103,8 @@ public:
* A version of Invoke() taking a variable number of individual arguments.
*/
template<class... Args>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>, ValPtr> Invoke(
Args&&... args) const {
requires std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>
ValPtr Invoke(Args&&... args) const {
auto zargs = zeek::Args{std::forward<Args>(args)...};
return Invoke(&zargs);
}

View file

@ -102,7 +102,8 @@ public:
IntrusivePtr(const IntrusivePtr& other) noexcept : IntrusivePtr(NewRef{}, other.get()) {}
template<class U, class = std::enable_if_t<std::is_convertible_v<U*, T*>>>
template<class U>
requires std::is_convertible_v<U*, T*>
IntrusivePtr(IntrusivePtr<U> other) noexcept : ptr_(other.release()) {
// nop
}

View file

@ -301,7 +301,7 @@ NFA_state_list* epsilon_closure(NFA_state_list* states) {
}
// Sort all of the closures in the list by ID
std::sort(closure->begin(), closure->end(), NFA_state_cmp_neg);
std::ranges::sort(*closure, NFA_state_cmp_neg);
// Make it fit.
closure->resize(0);

View file

@ -48,9 +48,7 @@ namespace zeek::detail {
uint32_t RuleHdrTest::idcounter = 0;
static bool is_member_of(const int_list& l, int_list::value_type v) {
return std::find(l.begin(), l.end(), v) != l.end();
}
static bool is_member_of(const int_list& l, int_list::value_type v) { return std::ranges::find(l, v) != l.end(); }
RuleHdrTest::RuleHdrTest(Prot arg_prot, uint32_t arg_offset, uint32_t arg_size, Comp arg_comp,
maskedvalue_list* arg_vals) {
@ -188,8 +186,7 @@ RuleEndpointState::RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_
}
const RuleEndpointState::RulePatternMatch* RuleEndpointState::FindRulePatternMatch(const Rule* r) const {
const auto it =
std::find_if(pattern_matches.begin(), pattern_matches.end(), [r](const auto& m) { return m.rule == r; });
const auto it = std::ranges::find_if(pattern_matches, [r](const auto& m) { return m.rule == r; });
if ( it != pattern_matches.end() )
return &(*it);

View file

@ -154,7 +154,7 @@ void ScriptCoverageManager::TrackUsage(const Location* loc, std::string desc, ui
loc->Describe(&location_info);
static canonicalize_desc cd{delim};
for_each(desc.begin(), desc.end(), cd);
std::ranges::for_each(desc, cd);
pair<string, string> location_desc(location_info.Description(), desc);

View file

@ -246,7 +246,7 @@ static void sw_collect_single(Substring::Vec* result, SWNodeMatrix& matrix, SWNo
else {
// printf("GAP\n");
if ( substring.size() >= params._min_toklen ) {
reverse(substring.begin(), substring.end());
std::ranges::reverse(substring);
auto* bst = new Substring(substring);
bst->AddAlignment(matrix.GetRowsString(), row - 1);
bst->AddAlignment(matrix.GetColsString(), col - 1);
@ -263,7 +263,7 @@ static void sw_collect_single(Substring::Vec* result, SWNodeMatrix& matrix, SWNo
// manually added and marked as the beginning of a new alignment.
//
if ( substring.size() > 0 ) {
reverse(substring.begin(), substring.end());
std::ranges::reverse(substring);
auto* bst = new Substring(substring);
bst->AddAlignment(matrix.GetRowsString(), row - 1);
bst->AddAlignment(matrix.GetColsString(), col - 1);
@ -488,9 +488,9 @@ Substring::Vec* smith_waterman(const String* s1, const String* s2, SWParams& par
sw_collect_single(result, matrix, node_max, params);
if ( len1 > len2 )
sort(result->begin(), result->end(), SubstringCmp(0));
std::ranges::sort(*result, SubstringCmp(0));
else
sort(result->begin(), result->end(), SubstringCmp(1));
std::ranges::sort(*result, SubstringCmp(1));
return result;
}

View file

@ -54,12 +54,12 @@ public:
template<size_t Size>
constexpr Span(element_type (&arr)[Size]) noexcept : memory_block(arr), num_elements(Size) {}
template<class Container, class Data = typename Container::value_type,
class = std::enable_if_t<std::is_convertible_v<Data*, T*>>>
template<class Container, class Data = typename Container::value_type>
requires std::is_convertible_v<Data*, T*>
Span(Container& xs) noexcept : memory_block(xs.data()), num_elements(xs.size()) {}
template<class Container, class Data = typename Container::value_type,
class = std::enable_if_t<std::is_convertible_v<const Data*, T*>>>
template<class Container, class Data = typename Container::value_type>
requires std::is_convertible_v<const Data*, T*>
Span(const Container& xs) noexcept : memory_block(xs.data()), num_elements(xs.size()) {}
constexpr Span(const Span&) noexcept = default;

View file

@ -469,7 +469,7 @@ void Manager::Process() {
}
void Manager::Queue(Trigger* trigger) {
if ( std::find(pending->begin(), pending->end(), trigger) == pending->end() ) {
if ( std::ranges::find(*pending, trigger) == pending->end() ) {
Ref(trigger);
pending->push_back(trigger);
trigger_count->Inc();

View file

@ -1493,7 +1493,7 @@ bool RecordType::IsDeferrable() const {
// If all creation_inits are deferrable, this record type is deferrable, too.
// It will be optimized later on. Note, all_of() returns true for an empty
// range, which is correct.
return std::all_of(creation_inits.begin(), creation_inits.end(), is_deferrable);
return std::ranges::all_of(creation_inits, is_deferrable);
}
FileType::FileType(TypePtr yield_type) : Type(TYPE_FILE), yield(std::move(yield_type)) {}

View file

@ -961,7 +961,8 @@ static zeek::expected<ValPtr, std::string> BuildVal(const rapidjson::Value& j, c
// Strip out any empty items. This can happen if there are
// strings of spaces in the original string.
parts.erase(std::remove_if(parts.begin(), parts.end(), [](auto x) { return x.empty(); }), parts.end());
parts.erase(std::ranges::begin(std::ranges::remove_if(parts, [](auto x) { return x.empty(); })),
std::end(parts));
if ( (parts.size() % 2) != 0 )
return zeek::unexpected<std::string>("wrong interval format, must be pairs of values with units");
@ -2565,7 +2566,7 @@ void TableVal::Describe(ODesc* d) const {
reporter->InternalError("hash table overflow in TableVal::Describe");
if ( determ ) {
sort(elem_descs.begin(), elem_descs.end());
ranges::sort(elem_descs);
bool did_elems = false;
for ( const auto& ed : elem_descs ) {
@ -3539,7 +3540,7 @@ void VectorVal::Sort(Func* cmp_func) {
}
}
sort(vector_val.begin(), vector_val.end(), sort_func);
ranges::sort(vector_val, sort_func);
}
VectorValPtr VectorVal::Order(Func* cmp_func) {
@ -3581,7 +3582,7 @@ VectorValPtr VectorVal::Order(Func* cmp_func) {
index_map.emplace_back(&vector_val[i]);
}
sort(ind_vv.begin(), ind_vv.end(), sort_func);
ranges::sort(ind_vv, sort_func);
index_map.clear();

View file

@ -1328,7 +1328,8 @@ public:
// access to record fields (without requiring an intermediary Val).
// It is up to the caller to ensure that the field exists in the
// record (using HasRawField(), if necessary).
template<typename T, typename std::enable_if_t<is_zeek_val_v<T>, bool> = true>
template<typename T>
requires is_zeek_val_v<T>
auto GetFieldAs(int field) const -> std::invoke_result_t<decltype(&T::Get), T> {
if constexpr ( std::is_same_v<T, BoolVal> || std::is_same_v<T, IntVal> || std::is_same_v<T, EnumVal> )
return record_val[field]->int_val;
@ -1365,7 +1366,8 @@ public:
}
}
template<typename T, typename std::enable_if_t<! is_zeek_val_v<T>, bool> = true>
template<typename T>
requires(! is_zeek_val_v<T>)
T GetFieldAs(int field) const {
if constexpr ( std::is_integral_v<T> && std::is_signed_v<T> )
return record_val[field]->int_val;

View file

@ -284,8 +284,6 @@ String* String::GetSubstring(int start, int len) const {
int String::FindSubstring(const String* s) const { return util::strstr_n(n, b, s->Len(), s->Bytes()); }
String::Vec* String::Split(const String::IdxVec& indices) const {
size_t i;
if ( indices.empty() )
return nullptr;
@ -296,26 +294,28 @@ String::Vec* String::Split(const String::IdxVec& indices) const {
idx.insert(idx.end(), indices.begin(), indices.end());
// Sanity checks.
for ( i = 0; i < idx.size(); ++i )
if ( idx[i] >= n || idx[i] < 0 )
idx[i] = 0;
std::ranges::transform(idx.begin(), idx.end(), idx.begin(), [this](int v) {
if ( v >= n || v < 0 )
return 0;
return v;
});
// Sort it:
sort(idx.begin(), idx.end());
std::ranges::sort(idx);
// Shuffle vector so duplicate entries are used only once:
IdxVecIt end = unique(idx.begin(), idx.end());
// Shuffle vector so duplicate entries are used only once. "ret" here is the first
// element after the last unique element. "last" should be the end of the vector.
auto [ret, last] = std::ranges::unique(idx);
// Each element in idx is now the start index of a new
// substring, and we know that all indices are within [0, n].
//
Vec* result = new Vec();
int last_idx = -1;
int next_idx;
i = 0;
result->reserve(std::distance(idx.begin(), ret));
for ( IdxVecIt it = idx.begin(); it != end; ++it, ++i ) {
int len = (it + 1 == end) ? -1 : idx[i + 1] - idx[i];
size_t i = 0;
for ( IdxVecIt it = idx.begin(); it != ret; ++it, ++i ) {
int len = (it + 1 == last) ? -1 : idx[i + 1] - idx[i];
result->push_back(GetSubstring(idx[i], len));
}
@ -442,7 +442,7 @@ String* concatenate(String::CVec& v) {
String* concatenate(String::Vec& v) {
String::CVec cv;
std::copy(v.begin(), v.end(), std::back_inserter<String::CVec>(cv));
std::ranges::copy(v, std::back_inserter<String::CVec>(cv));
return concatenate(cv);
}
@ -673,11 +673,11 @@ TEST_CASE("misc") {
delete s;
std::vector<zeek::String*> sv2 = {new zeek::String{"abcde"}, new zeek::String{"fghi"}};
std::sort(sv2.begin(), sv2.end(), zeek::StringLenCmp(true));
std::ranges::sort(sv2, zeek::StringLenCmp(true));
CHECK_EQ(*(sv2.front()), "fghi");
CHECK_EQ(*(sv2.back()), "abcde");
std::sort(sv2.begin(), sv2.end(), zeek::StringLenCmp(false));
std::ranges::sort(sv2, zeek::StringLenCmp(false));
CHECK_EQ(*(sv2.front()), "abcde");
CHECK_EQ(*(sv2.back()), "fghi");

View file

@ -419,7 +419,7 @@ void Analyzer::PreventChildren(const zeek::Tag& tag) {
}
bool Analyzer::IsPreventedChildAnalyzer(const zeek::Tag& tag) const {
return std::find(prevented.begin(), prevented.end(), tag) != prevented.end();
return std::ranges::find(prevented, tag) != prevented.end();
}
bool Analyzer::HasChildAnalyzer(const zeek::Tag& tag) const { return GetChildAnalyzer(tag) != nullptr; }
@ -693,7 +693,7 @@ void Analyzer::CancelTimers() {
// traversing. Thus, we first make a copy of the list which we then
// iterate through.
TimerPList tmp(timers.length());
std::copy(timers.begin(), timers.end(), back_inserter(tmp));
std::ranges::copy(timers, back_inserter(tmp));
// TODO: could be a for_each
for ( auto timer : tmp )

View file

@ -624,8 +624,8 @@ public:
* A version of EnqueueConnEvent() taking a variable number of arguments.
*/
template<class... Args>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>> EnqueueConnEvent(
EventHandlerPtr h, Args&&... args) {
requires std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>
void EnqueueConnEvent(EventHandlerPtr h, Args&&... args) {
return EnqueueConnEvent(h, zeek::Args{std::forward<Args>(args)...});
}

View file

@ -31,7 +31,7 @@ public:
auto lv = t->ToPureListVal();
for ( auto i = 0; i < lv->Length(); i++ )
thresholds.emplace_back(lv->Idx(i)->AsCount());
std::sort(thresholds.begin(), thresholds.end());
std::ranges::sort(thresholds);
zeek::analyzer::conn_size::ConnSize_Analyzer::SetGenericPacketThresholds(std::move(thresholds));
}

View file

@ -346,7 +346,7 @@ void HTTP_Entity::SubmitHeader(analyzer::mime::MIME_Header* h) {
std::string byte_unit(vt.data, vt.length);
vt = h->get_value_after_token();
std::string byte_range(vt.data, vt.length);
byte_range.erase(remove(byte_range.begin(), byte_range.end(), ' '), byte_range.end());
byte_range.erase(std::ranges::begin(std::ranges::remove(byte_range, ' ')), std::end(byte_range));
if ( byte_unit != "bytes" ) {
http_message->Weird("HTTP_content_range_unknown_byte_unit");

View file

@ -14,7 +14,7 @@ refine connection IMAP_Conn += {
function proc_imap_token(is_orig: bool, tag: bytestring, command: bytestring): bool
%{
string commands = std_str(command);
std::transform(commands.begin(), commands.end(), commands.begin(), ::tolower);
std::ranges::transform(commands, commands.begin(), ::tolower);
string tags = std_str(tag);

View file

@ -52,7 +52,7 @@ refine connection IMAP_Conn += {
function determine_command(is_orig: bool, tag: bytestring, command: bytestring): int
%{
string cmdstr = std_str(command);
std::transform(cmdstr.begin(), cmdstr.end(), cmdstr.begin(), ::tolower);
std::ranges::transform(cmdstr, cmdstr.begin(), ::tolower);
if ( !is_orig && cmdstr == "capability" && tag == "*" ) {
return CMD_CAPABILITY;

View file

@ -22,30 +22,28 @@ refine connection SSL_Conn += {
if ( ssl_client_hello )
{
vector<int> cipher_suites;
if ( cipher_suites16 )
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites));
else
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int());
auto cipher_vec = zeek::make_intrusive<zeek::VectorVal>(zeek::id::index_vec);
for ( unsigned int i = 0; i < cipher_suites.size(); ++i )
if ( cipher_suites16 )
{
auto cipher = zeek::val_mgr->Count(cipher_suites[i]);
cipher_vec->Assign(i, std::move(cipher));
cipher_vec->Reserve(cipher_suites16->size());
for ( uint32_t cipher : *cipher_suites16 )
cipher_vec->Append(zeek::val_mgr->Count(cipher));
}
else
{
cipher_vec->Reserve(cipher_suites24->size());
for ( auto cipher : *cipher_suites24 )
cipher_vec->Append(zeek::val_mgr->Count(to_int()(cipher)));
}
auto comp_vec = zeek::make_intrusive<zeek::VectorVal>(zeek::id::index_vec);
if ( compression_methods )
{
for ( unsigned int i = 0; i < compression_methods->size(); ++i )
{
auto comp = zeek::val_mgr->Count((*compression_methods)[i]);
comp_vec->Assign(i, comp);
}
comp_vec->Reserve(compression_methods->size());
for ( auto method : *compression_methods )
comp_vec->Append(zeek::val_mgr->Count(method));
}
zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(),
@ -75,12 +73,11 @@ refine connection SSL_Conn += {
if ( ssl_server_hello )
{
vector<int>* ciphers = new vector<int>();
if ( cipher_suites16 )
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers));
else
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int());
int first_cipher = 0;
if ( cipher_suites16 && ! cipher_suites16->empty() )
first_cipher = cipher_suites16->front();
else if ( cipher_suites24 && ! cipher_suites24->empty() )
first_cipher = to_int()(cipher_suites24->front());
uint32 ts = 0;
if ( v2 == 0 && server_random.length() >= 4 )
@ -92,9 +89,7 @@ refine connection SSL_Conn += {
zeek::make_intrusive<zeek::StringVal>(server_random.length(),
(const char*) server_random.data()),
{zeek::AdoptRef{}, to_string_val(session_id)},
ciphers->size()==0 ? 0 : ciphers->at(0), comp_method);
delete ciphers;
first_cipher, comp_method);
}
return true;

View file

@ -48,9 +48,9 @@ refine connection Handshake_Conn += {
vector<int> cipher_suites;
if ( cipher_suites16 )
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites));
std::ranges::copy(*cipher_suites16, std::back_inserter(cipher_suites));
else
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int());
std::ranges::transform(*cipher_suites24, std::back_inserter(cipher_suites), to_int());
auto cipher_vec = zeek::make_intrusive<zeek::VectorVal>(zeek::id::index_vec);
@ -103,9 +103,9 @@ refine connection Handshake_Conn += {
vector<int>* ciphers = new vector<int>();
if ( cipher_suites16 )
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers));
std::ranges::copy(*cipher_suites16, std::back_inserter(*ciphers));
else
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int());
std::ranges::transform(*cipher_suites24, std::back_inserter(*ciphers), to_int());
uint32 ts = 0;
if ( v2 == 0 && server_random.length() >= 4 )
@ -374,8 +374,7 @@ refine connection Handshake_Conn += {
vector<X509Certificate*>* certs = cl;
vector<bytestring>* cert_list = new vector<bytestring>();
std::transform(certs->begin(), certs->end(),
std::back_inserter(*cert_list), extract_certs());
std::ranges::transform(*certs, std::back_inserter(*cert_list), extract_certs());
bool ret = proc_certificate(is_orig, flipped_, cert_list);
delete cert_list;

View file

@ -493,7 +493,8 @@ public:
BrokerData() = default;
template<class DataType, class = std::enable_if_t<std::is_same_v<DataType, broker::data>>>
template<class DataType>
requires std::is_same_v<DataType, broker::data>
explicit BrokerData(DataType value) : value_(std::move(value)) {
// Note: we use enable_if here to avoid nasty implicit conversions of broker::data.
}

View file

@ -297,7 +297,7 @@ void WebSocketEventDispatcher::Process(const WebSocketOpen& open) {
std::string application_name = open.application_name.value_or("unknown");
// A bit ad-hoc
bool good_application_name = std::all_of(application_name.begin(), application_name.end(), [](auto c) {
bool good_application_name = std::ranges::all_of(application_name, [](auto c) {
return std::isalnum(c) || c == '/' || c == '_' || c == '-' || c == '.' || c == '=' || c == ':' || c == '*' ||
c == '@';
});

View file

@ -185,7 +185,7 @@ bool Ascii::ReadHeader(bool useCached) {
for ( int i = 0; i < NumFields(); i++ ) {
const Field* field = fields[i];
auto fit = std::find(ifields.begin(), ifields.end(), field->name);
auto fit = std::ranges::find(ifields, field->name);
if ( fit == ifields.end() ) {
if ( field->optional ) {
// we do not really need this field. mark it as not present and always send an undef
@ -206,7 +206,7 @@ bool Ascii::ReadHeader(bool useCached) {
FieldMapping f(field->name, field->type, field->subtype, index);
if ( field->secondary_name && strlen(field->secondary_name) != 0 ) {
auto fit2 = std::find(ifields.begin(), ifields.end(), field->secondary_name);
auto fit2 = std::ranges::find(ifields, field->secondary_name);
if ( fit2 == ifields.end() ) {
FailWarn(fail_on_file_problem,
Fmt("Could not find requested port type field %s in input data file %s.",

View file

@ -23,7 +23,7 @@ bool None::DoInit(const WriterInfo& info, int num_fields, const threading::Field
for ( const auto& [key, value] : info.config )
keys.emplace_back(key, value);
std::sort(keys.begin(), keys.end());
std::ranges::sort(keys);
for ( const auto& [key, value] : keys )
std::cout << " config[" << key << "] = " << value << "\n";

View file

@ -101,7 +101,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai
constexpr auto eth_len = 14;
if ( validate_checksum && len > ((int)sizeof(struct udphdr) + vxlan_len + eth_len) && (data[0] & 0x08) == 0x08 ) {
if ( std::find(vxlan_ports.begin(), vxlan_ports.end(), ntohs(up->uh_dport)) != vxlan_ports.end() ) {
if ( std::ranges::find(vxlan_ports, ntohs(up->uh_dport)) != vxlan_ports.end() ) {
// Looks like VXLAN on a well-known port, so the checksum should be
// transmitted as zero, and we should accept that. If not
// transmitted as zero, then validating the checksum is optional.

View file

@ -313,7 +313,7 @@ BitVector& BitVector::Set(size_type i, bool bit) {
}
BitVector& BitVector::Set() {
std::fill(bits.begin(), bits.end(), ~block_type(0));
std::ranges::fill(bits, ~block_type(0));
zero_unused_bits();
return *this;
}
@ -325,7 +325,7 @@ BitVector& BitVector::Reset(size_type i) {
}
BitVector& BitVector::Reset() {
std::fill(bits.begin(), bits.end(), block_type(0));
std::ranges::fill(bits, block_type(0));
return *this;
}

View file

@ -5,6 +5,7 @@
#include <cinttypes>
#include <cmath>
#include <limits>
#include <numbers>
#include "zeek/Reporter.h"
#include "zeek/broker/Data.h"
@ -86,13 +87,13 @@ bool BloomFilter::DoUnserializeData(BrokerDataView data) {
}
size_t BasicBloomFilter::M(double fp, size_t capacity) {
double ln2 = std::log(2);
double ln2 = std::numbers::ln2;
return std::ceil(-(capacity * std::log(fp) / ln2 / ln2));
}
size_t BasicBloomFilter::K(size_t cells, size_t capacity) {
double frac = static_cast<double>(cells) / static_cast<double>(capacity);
return std::ceil(frac * std::log(2));
return std::ceil(frac * std::numbers::ln2);
}
bool BasicBloomFilter::Empty() const { return bits->AllZero(); }

View file

@ -5,6 +5,7 @@
#include <cinttypes>
#include <cmath>
#include <cstdint>
#include <numbers>
#include <utility>
#include "zeek/Reporter.h"
@ -13,7 +14,7 @@
namespace zeek::probabilistic::detail {
int CardinalityCounter::OptimalB(double error, double confidence) const {
double initial_estimate = 2 * (log(1.04) - log(error)) / log(2);
double initial_estimate = 2 * (log(1.04) - log(error)) / std::numbers::ln2;
int answer = (int)floor(initial_estimate);
// k is the number of standard deviations that we have to go to have
@ -24,7 +25,7 @@ int CardinalityCounter::OptimalB(double error, double confidence) const {
do {
answer++;
k = pow(2, (answer - initial_estimate) / 2);
} while ( erf(k / sqrt(2)) < confidence );
} while ( erf(k / std::numbers::sqrt2) < confidence );
return answer;
}

View file

@ -192,7 +192,7 @@ string CPPCompile::BodyName(const FuncInfo& func) {
auto canonicalize = [](char c) -> char { return isalnum(c) ? c : '_'; };
string fns = fn;
transform(fns.begin(), fns.end(), fns.begin(), canonicalize);
std::ranges::transform(fns, fns.begin(), canonicalize);
if ( ! isalpha(fns[0]) )
// This can happen for filenames beginning with numbers.

View file

@ -3065,10 +3065,10 @@ IDPtr ConstructFromRecordExpr::FindMostCommonRecordSource(const ListExprPtr& exp
return nullptr;
// Return the most common.
auto max_entry = std::max_element(id_cnt.begin(), id_cnt.end(),
[](const std::pair<IDPtr, int>& p1, const std::pair<IDPtr, int>& p2) {
return p1.second < p2.second;
});
auto max_entry =
std::ranges::max_element(id_cnt, [](const std::pair<IDPtr, int>& p1, const std::pair<IDPtr, int>& p2) {
return p1.second < p2.second;
});
return max_entry->first;
}

View file

@ -173,7 +173,7 @@ void Manager::Drain() {
for ( auto& entry : session_map )
keys.push_back(&(entry.first));
std::sort(keys.begin(), keys.end(), [](const detail::Key* a, const detail::Key* b) { return *a < *b; });
std::ranges::sort(keys, [](const detail::Key* a, const detail::Key* b) { return *a < *b; });
for ( const auto* k : keys ) {
Session* tc = session_map.at(*k);

View file

@ -121,7 +121,7 @@ void Session::CancelTimers() {
// traversing. Thus, we first make a copy of the list which we then
// iterate through.
TimerPList tmp(timers.length());
std::copy(timers.begin(), timers.end(), std::back_inserter(tmp));
std::ranges::copy(timers, std::back_inserter(tmp));
for ( const auto& timer : tmp )
zeek::detail::timer_mgr->Cancel(timer);

View file

@ -130,8 +130,8 @@ public:
* A version of EnqueueEvent() taking a variable number of arguments.
*/
template<class... Args>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>> EnqueueEvent(
EventHandlerPtr h, analyzer::Analyzer* analyzer, Args&&... args) {
requires std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>
void EnqueueEvent(EventHandlerPtr h, analyzer::Analyzer* analyzer, Args&&... args) {
return EnqueueEvent(h, analyzer, zeek::Args{std::forward<Args>(args)...});
}

View file

@ -80,8 +80,10 @@ void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Proto
// Store ports in a deterministic order. We can't (easily) sort the
// `hilti::rt::Vector` unfortunately.
std::copy(ports.begin(), ports.end(), std::back_inserter(info.ports));
std::sort(info.ports.begin(), info.ports.end());
std::ranges::copy(ports, std::back_inserter(info.ports));
std::ranges::sort(info.ports, [](const ::zeek::spicy::rt::PortRange& l, const ::zeek::spicy::rt::PortRange& r) {
return l < r;
});
// We may have that analyzer already iff it was previously pre-registered
// without a linker scope. We'll then only set the scope now.

View file

@ -111,7 +111,7 @@ OperationResult Manager::CloseBackend(BackendPtr backend, ResultCallback* cb) {
// backend from the vector before actually closing it.
{
std::unique_lock<std::mutex> lk(backends_mtx);
auto it = std::find(backends.begin(), backends.end(), backend);
auto it = std::ranges::find(backends, backend);
if ( it != backends.end() )
backends.erase(it);
}

View file

@ -21,7 +21,7 @@ std::optional<byte_buffer> JSON::Serialize(ValPtr val) {
auto json = val->ToJSON();
buf.reserve(json->Len() + versioned_name.size() + 1);
std::transform(versioned_name.begin(), versioned_name.end(), std::back_inserter(buf), byte_converter);
std::ranges::transform(versioned_name, std::back_inserter(buf), byte_converter);
buf.push_back(static_cast<std::byte>(';'));
std::transform(json->Bytes(), json->Bytes() + json->Len(), std::back_inserter(buf), byte_converter);

View file

@ -21,7 +21,7 @@ std::shared_ptr<Counter> CounterFamily::GetOrAdd(Span<const LabelView> labels, d
auto check = [&](const std::shared_ptr<Counter>& counter) { return counter->CompareLabels(p_labels); };
if ( auto it = std::find_if(counters.begin(), counters.end(), check); it != counters.end() )
if ( auto it = std::ranges::find_if(counters, check); it != counters.end() )
return *it;
auto counter = std::make_shared<Counter>(family, p_labels, callback);

View file

@ -22,7 +22,7 @@ std::shared_ptr<Gauge> GaugeFamily::GetOrAdd(Span<const LabelView> labels, detai
auto check = [&](const std::shared_ptr<Gauge>& gauge) { return gauge->CompareLabels(p_labels); };
if ( auto it = std::find_if(gauges.begin(), gauges.end(), check); it != gauges.end() )
if ( auto it = std::ranges::find_if(gauges, check); it != gauges.end() )
return *it;
auto gauge = std::make_shared<Gauge>(family, p_labels, callback);

View file

@ -20,7 +20,7 @@ std::shared_ptr<Histogram> HistogramFamily::GetOrAdd(Span<const LabelView> label
auto check = [&](const std::shared_ptr<Histogram>& histo) { return histo->CompareLabels(p_labels); };
if ( auto it = std::find_if(histograms.begin(), histograms.end(), check); it != histograms.end() )
if ( auto it = std::ranges::find_if(histograms, check); it != histograms.end() )
return *it;
auto histogram = std::make_shared<Histogram>(family, p_labels, boundaries);
@ -38,5 +38,5 @@ std::shared_ptr<Histogram> HistogramFamily::GetOrAdd(std::initializer_list<Label
HistogramFamily::HistogramFamily(prometheus::Family<prometheus::Histogram>* family, Span<const double> bounds,
Span<const std::string_view> labels)
: MetricFamily(labels), family(family) {
std::copy(bounds.begin(), bounds.end(), std::back_inserter(boundaries));
std::ranges::copy(bounds, std::back_inserter(boundaries));
}

View file

@ -364,7 +364,7 @@ ValPtr Manager::CollectMetrics(std::string_view prefix_pattern, std::string_view
static auto running_under_test = id::find_val("running_under_test")->AsBool();
if ( running_under_test ) {
auto& vec = ret_val->RawVec();
std::sort(vec.begin(), vec.end(), compare_metrics);
std::ranges::sort(vec, compare_metrics);
}
}
@ -464,7 +464,7 @@ ValPtr Manager::CollectHistogramMetrics(std::string_view prefix_pattern, std::st
static auto running_under_test = id::find_val("running_under_test")->AsBool();
if ( running_under_test ) {
auto& vec = ret_val->RawVec();
std::sort(vec.begin(), vec.end(), compare_histograms);
std::ranges::sort(vec, compare_histograms);
}
}

View file

@ -20,7 +20,7 @@ std::string BuildFullPrometheusName(std::string_view prefix, std::string_view na
std::string fn = util::fmt("%.*s_%.*s", static_cast<int>(prefix.size()), prefix.data(),
static_cast<int>(name.size()), name.data());
std::for_each(fn.begin(), fn.end(), [](char& c) {
std::ranges::for_each(fn, [](char& c) {
if ( ! std::isalnum(c) )
c = '_';
});

View file

@ -41,6 +41,7 @@
#include <array>
#include <filesystem>
#include <iostream>
#include <ranges>
#include <sstream>
#include <string>
#include <vector>
@ -1146,7 +1147,7 @@ void to_upper(char* s) {
string to_upper(const std::string& s) {
string t = s;
std::transform(t.begin(), t.end(), t.begin(), ::toupper);
std::ranges::transform(t, t.begin(), ::toupper);
return t;
}
@ -1392,7 +1393,7 @@ TEST_CASE("util strtolower") {
std::string strtolower(const std::string& s) {
std::string t = s;
std::transform(t.begin(), t.end(), t.begin(), ::tolower);
std::ranges::transform(t, t.begin(), ::tolower);
return t;
}
@ -1406,7 +1407,7 @@ TEST_CASE("util strtoupper") {
std::string strtoupper(const std::string& s) {
std::string t = s;
std::transform(t.begin(), t.end(), t.begin(), ::toupper);
std::ranges::transform(t, t.begin(), ::toupper);
return t;
}
@ -1536,8 +1537,8 @@ TEST_CASE("util strstrip") {
std::string strstrip(std::string s) {
auto notspace = [](unsigned char c) { return ! std::isspace(c); };
s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
s.erase(s.begin(), std::ranges::find_if(s, notspace));
s.erase(std::ranges::find_if(std::ranges::reverse_view(s), notspace).base(), s.end());
return s;
}

View file

@ -46,7 +46,7 @@ Config::Config(string arg_file, const string& delim)
++line_number;
vector<string> tokens;
util::tokenize_string(line, delim, &tokens);
tokens.erase(remove(tokens.begin(), tokens.end(), ""), tokens.end());
tokens.erase(std::ranges::begin(std::ranges::remove(tokens, "")), std::end(tokens));
if ( tokens.empty() )
// Blank line.

View file

@ -113,7 +113,7 @@ size_t end_of_first_sentence(const string& s) {
}
bool is_all_whitespace(const string& s) {
auto it = std::find_if(s.begin(), s.end(), [](char c) { return ! isspace(c); });
auto it = std::ranges::find_if(s, [](char c) { return ! isspace(c); });
return it == s.end();
}