From 61a0395ae7c0bfaae715e958b287e0df64c7aae5 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Sun, 7 Apr 2024 20:45:06 -0400 Subject: [PATCH] llil.cc - make string_cnt a template. --- examples/llil.cc | 58 +++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/examples/llil.cc b/examples/llil.cc index c36f8d5..aa7dc13 100644 --- a/examples/llil.cc +++ b/examples/llil.cc @@ -124,59 +124,63 @@ struct stats_t { // --------------------------------------------------------------------------------------------- // Stores a string + a count -// For strings up to 11 bytes, total space used is 16 bytes (no wasted space in set) +// For strings up to N-1 bytes, total space used is N + 4 bytes // For larger strings, uses 16 bytes + strlen(string) + 1 // // invariants -// if extra[3], str is a valid string pointer -// if !extra[3], the 12 bytes starting at (const char *)(&str) store a null_terminated string +// if extra[mark_idx], str is a valid string pointer +// if !extra[mark_idx], the N bytes starting at (const char *)(&str) store a null_terminated string // --------------------------------------------------------------------------------------------- -struct string_cnt { +template +struct string_cnt_t { using uint_t = uint32_t; + static constexpr size_t extra_sz = N - sizeof(char*); + static constexpr size_t mark_idx = extra_sz - 1; + char * str; - char extra[4]; + char extra[extra_sz]; uint_t cnt; static constexpr size_t buffsz = sizeof(str) + sizeof(extra); - string_cnt() : str{nullptr}, extra{0,0,0,0}, cnt{0} {} + string_cnt_t() : str{nullptr}, extra{0,0,0,0}, cnt{0} {} - string_cnt(std::string_view s, uint_t c = 0) : str(nullptr), cnt(c) { set(s); } + string_cnt_t(std::string_view s, uint_t c = 0) : str(nullptr), cnt(c) { set(s); } - ~string_cnt() { free(); } + ~string_cnt_t() { free(); } - string_cnt(const string_cnt& o) { + string_cnt_t(const string_cnt_t& o) { set(o.get()); } - string_cnt(string_cnt&& o) noexcept { - if (o.extra[3]) { + string_cnt_t(string_cnt_t&& o) noexcept { + if (o.extra[mark_idx]) { str = o.str; o.str = nullptr; - extra[3] = 1; + extra[mark_idx] = 1; } else { std::strcpy((char *)(&str), o.get()); - extra[3] = 0; + extra[mark_idx] = 0; } cnt = o.cnt; } - string_cnt& operator=(const string_cnt& o) { + string_cnt_t& operator=(const string_cnt_t& o) { free(); set(o.get()); cnt = o.cnt; return *this; } - string_cnt& operator=(string_cnt&& o) noexcept { + string_cnt_t& operator=(string_cnt_t&& o) noexcept { free(); - new (this) string_cnt(std::move(o)); + new (this) string_cnt_t(std::move(o)); return *this; } - std::strong_ordering operator<=>(const string_cnt& o) const { return std::strcmp(get(), o.get()) <=> 0; } - bool operator==(const string_cnt& o) const { return std::strcmp(get(), o.get()) == 0; } + std::strong_ordering operator<=>(const string_cnt_t& o) const { return std::strcmp(get(), o.get()) <=> 0; } + bool operator==(const string_cnt_t& o) const { return std::strcmp(get(), o.get()) == 0; } std::size_t hash() const { auto s = get(); @@ -184,17 +188,17 @@ struct string_cnt { return std::hash()(sv); } - const char *get() const { return extra[3] ? str : (const char *)(&str); } + const char *get() const { return extra[mark_idx] ? str : (const char *)(&str); } private: - void free() { if (extra[3]) { delete [] str; str = nullptr; } } + void free() { if (extra[mark_idx]) { delete [] str; str = nullptr; } } void set(std::string_view s) { static_assert(buffsz == 12); - static_assert(offsetof(string_cnt, cnt) == (intptr_t)buffsz); - static_assert(sizeof(string_cnt) == 16); + static_assert(offsetof(string_cnt_t, cnt) == (intptr_t)buffsz); + static_assert(sizeof(string_cnt_t) == 16); - assert(!extra[3] || !str); + assert(!extra[mark_idx] || !str); if (s.empty()) std::memset(&str, 0, buffsz); else { @@ -203,11 +207,11 @@ private: str = new char[len+1]; std::memcpy(str, s.data(), len); str[len] = 0; - extra[3] = 1; + extra[mark_idx] = 1; } else { std::memcpy((char *)(&str), s.data(), len); ((char *)&str)[len] = 0; - extra[3] = 0; + extra[mark_idx] = 0; } } } @@ -217,6 +221,8 @@ private: } }; +using string_cnt = string_cnt_t<12>; + namespace std { template<> struct hash { std::size_t operator()(const string_cnt& v) const noexcept { return v.hash(); }; @@ -376,6 +382,7 @@ private: } void process_vec(size_t subidx, string_cnt_vector_t* v) { +#if 1 set.with_submap_m(subidx, [&](auto& s) { for (auto& sc : *v) { auto it = s.find(sc); @@ -385,6 +392,7 @@ private: const_cast(*it).cnt += sc.cnt; } }); +#endif delete v; }