From c6ba8aa5c3e9594ad4a491662e8f406c162288b6 Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 28 Jan 2026 15:53:31 +0200 Subject: [PATCH] ctor/dtor improvements --- src/admin.cpp | 6 +-- src/db.hpp | 14 ++---- src/irc.cpp | 25 ++-------- src/irc.hpp | 1 - src/ircdata.hpp | 130 ++++++++++++++++++++++++------------------------ src/ircfmt.cpp | 4 +- src/map.cpp | 6 ++- src/map.hpp | 8 ++- 8 files changed, 89 insertions(+), 105 deletions(-) diff --git a/src/admin.cpp b/src/admin.cpp index fee79be..6daf73c 100644 --- a/src/admin.cpp +++ b/src/admin.cpp @@ -273,10 +273,8 @@ static int fn_channel_new(lua_State *L) memcpy(key, channel, chanlen+1); stringlower(key); Channel *chan = channel_map.get(key); - if (!chan) { - chan = channel_new(channel, key, creation ? creation : get_time()); - channel_map.add(chan); - } + if (!chan) + chan = new Channel(channel, key, creation ? creation : get_time()); return 0; } static int fn_channel_mode(lua_State *L) diff --git a/src/db.hpp b/src/db.hpp index 6402af1..aa922f7 100644 --- a/src/db.hpp +++ b/src/db.hpp @@ -11,14 +11,12 @@ namespace db { Database() :db(0) {}; explicit Database(const char *fn); ~Database(); - Database(const Database&) = delete; - Database& operator=(const Database&) = delete; - Database(Database&& other) { db = std::exchange(other.db, nullptr); } - Database& operator=(Database&& other) { + Database(Database&& other) noexcept { db = std::exchange(other.db, nullptr); } + Database& operator=(Database&& other) noexcept { swap(*this, other); return *this; } - friend void swap(Database &lhs, Database &rhs) { + friend void swap(Database &lhs, Database &rhs) noexcept { using std::swap; swap(lhs.db, rhs.db); } @@ -28,10 +26,8 @@ namespace db { sqlite3_stmt *stmt; Statement() :stmt(0) {}; ~Statement(); - Statement(const Statement&) = delete; - Statement& operator=(const Statement&) = delete; - Statement(Statement&& other) { stmt = std::exchange(other.stmt, nullptr); } - Statement& operator=(Statement&& other) { + Statement(Statement&& other) noexcept { stmt = std::exchange(other.stmt, nullptr); } + Statement& operator=(Statement&& other) noexcept { swap(*this, other); return *this; } diff --git a/src/irc.cpp b/src/irc.cpp index 69a3414..8e7f6ed 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -1500,9 +1500,8 @@ void channel_join(Client *client, const char *channel, const char *chankey) Channel *chan = channel_map.get(key); int newchan = !chan; if (!chan) { - chan = channel_new(channel, key, get_time()); + chan = new Channel(channel, key, get_time()); chan->dmode &= ~DMODE_PERSIST; - channel_map.add(chan); chan->o.add(client); } else { if (chan->members.has(client)) @@ -1549,16 +1548,10 @@ void channel_join(Client *client, const char *channel, const char *chankey) // send names channel_sendnames(client, chan); } -Channel *channel_new(const char *channel, const char *key, time_t creation) +Channel::Channel(const char *channel, const char *key, time_t creation) + :key(mystrdup(key)), name(mystrdup(channel)), creation(creation) { - Channel *chan = new Channel(); - memset(chan, 0, sizeof(Channel)); - chan->creation = creation; - chan->member_limit = -1; - chan->dmode = DMODE_NOEXTERNAL | DMODE_TOPICPROT | DMODE_PERSIST; - chan->key = mystrdup(key); - chan->name = mystrdup(channel); - return chan; + channel_map.add(this); } void channel_part(Client *client, Channel *chan, const char *reason, Client *kicker) { @@ -1591,16 +1584,6 @@ Channel::~Channel() { delete[] name; delete[] topic; delete[] topic_who; - members.clear(); - o.clear(); - v.clear(); - listb.clear(); - liste.clear(); - listI.clear(); - listq.clear(); - listwo.clear(); - listwv.clear(); - invitees.clear(); delete[] chankey; } void channel_mode(Client *client, Channel *chan, char *args[]) { diff --git a/src/irc.hpp b/src/irc.hpp index 97a83d1..9f94383 100644 --- a/src/irc.hpp +++ b/src/irc.hpp @@ -21,7 +21,6 @@ Channel *findChannel(const char *channel); void channel_sendtopic(Client *client, Channel *chan, int joining); void channel_sendnames(Client *client, Channel *chan); void channel_join(Client *client, const char *channel, const char *chankey); -Channel *channel_new(const char *channel, const char *key, time_t creation); void channel_part(Client *client, Channel *chan, const char *reason, Client *kicker); void channel_kill(Channel *chan); void channel_mode(Client *client, Channel *chan, char *args[]); diff --git a/src/ircdata.hpp b/src/ircdata.hpp index dcef261..419f6bd 100644 --- a/src/ircdata.hpp +++ b/src/ircdata.hpp @@ -29,67 +29,71 @@ #define CAP_SETNAME 128 #define CAP_ACCOUNTNOTIFY 256 struct Client { - char *key; // case-mapped nick - uv_os_sock_t fd; - struct tls *cctx; - struct Client *next; - char *nick; - char *username; - char *realname; - char *hostname; - char *nuh; // case-mapped nick!user@host - char *away; - char *nick_reg; - char *pass_reg; - char *peername; - unsigned short peerport; - char *saslbuf; - size_t saslbufLen; - char *saslusername; - char *webircpeername; - char *webirchostname; - char rbuf[2048]; - size_t rlen; - char wbuf[8192]; - size_t wlen; - char umode; - char regstate; + char *key = nullptr; // case-mapped nick + uv_os_sock_t fd = -1; + struct tls *cctx = nullptr; + struct Client *next = nullptr; + char *nick = nullptr; + char *username = nullptr; + char *realname = nullptr; + char *hostname = nullptr; + char *nuh = nullptr; // case-mapped nick!user@host + char *away = nullptr; + char *nick_reg = nullptr; + char *pass_reg = nullptr; + char *peername = nullptr; + unsigned short peerport = 0; + char *saslbuf = nullptr; + size_t saslbufLen = 0; + char *saslusername = nullptr; + char *webircpeername = nullptr; + char *webirchostname = nullptr; + char rbuf[2048] = {0}; + size_t rlen = 0; + char wbuf[8192] = {0}; + size_t wlen = 0; + char umode = 0; + char regstate = REG_INIT; channelmap channels; channelmap invites; stringset monitor; - int cookie; - time_t signon; - time_t lastactivity; - unsigned int caps; - unsigned want_write_for_read :1; - unsigned want_read_for_write :1; - unsigned want_write_for_write :1; - unsigned want_read_for_close :1; - unsigned want_write_for_close :1; - unsigned dying :1; - unsigned write_error :1; - unsigned poll_reg :2; - unsigned saslexternal :1; - unsigned passwait :1; - unsigned webircwait :2; + int cookie = 0; + time_t signon = 0; + time_t lastactivity = 0; + unsigned int caps = 0; + unsigned want_write_for_read :1 = 0; + unsigned want_read_for_write :1 = 0; + unsigned want_write_for_write :1 = 0; + unsigned want_read_for_close :1 = 0; + unsigned want_write_for_close :1 = 0; + unsigned dying :1 = 0; + unsigned write_error :1 = 0; + unsigned poll_reg :2 = 0; + unsigned saslexternal :1 = 0; + unsigned passwait :1 = 0; + unsigned webircwait :2 = 0; - Client() = default; - Client(const Client&) = delete; - Client& operator=(const Client&) = delete; + Client& operator=(Client&&) = delete; ~Client(); }; +#define DMODE_PERSIST 1 +#define DMODE_INVITEONLY 2 +#define DMODE_MODERATED 4 +#define DMODE_NOEXTERNAL 8 +#define DMODE_SECRET 16 +#define DMODE_TOPICPROT 32 struct Channel { - char *key; - char *name; - char *topic; - char *topic_who; - time_t topic_when; - time_t creation; + char *key = nullptr; + char *name = nullptr; + char *topic = nullptr; + char *topic_who = nullptr; + time_t topic_when = 0; + time_t creation = 0; clientmap members; clientmap o; clientmap v; - int member_count; - char dmode; + int member_count = 0; + char dmode = DMODE_NOEXTERNAL | DMODE_TOPICPROT | DMODE_PERSIST; stringset listb; stringset liste; stringset listI; @@ -97,22 +101,20 @@ struct Channel { stringset listwo; stringset listwv; clientmap invitees; - char *chankey; - int member_limit; + char *chankey = nullptr; + int member_limit = -1; - Channel() = default; - Channel(const Channel&) = delete; - Channel& operator=(const Channel&) = delete; + Channel(const char *channel, const char *key, time_t creation); + Channel& operator=(Channel&&) = delete; ~Channel(); + + bool is_op(Client *client) { + return o.has(client); + } + bool is_voice(Client *client) { + return v.has(client); + } }; -#define DMODE_PERSIST 1 -#define DMODE_INVITEONLY 2 -#define DMODE_MODERATED 4 -#define DMODE_NOEXTERNAL 8 -#define DMODE_SECRET 16 -#define DMODE_TOPICPROT 32 -#define is_chanop(chan, client) (!!(chan)->o.has((client))) -#define is_chanvoice(chan, client) (!!(chan)->v.has((client))) extern clientmap client_map; extern channelmap channel_map; extern stringset autojoin; diff --git a/src/ircfmt.cpp b/src/ircfmt.cpp index cc3c280..79bc827 100644 --- a/src/ircfmt.cpp +++ b/src/ircfmt.cpp @@ -4,8 +4,8 @@ #include "ircfmt.hpp" static const char *format_prefixes(Client *client, Client *cl, Channel *chan) { if (!chan) return ""; - int o = is_chanop(chan, cl); - int v = is_chanvoice(chan, cl); + bool o = chan->is_op(cl); + bool v = chan->is_voice(cl); if (client->caps & CAP_MULTIPREFIX && o && v) return "@+"; else if (o) diff --git a/src/map.cpp b/src/map.cpp index 721eccf..0134dac 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -70,8 +70,7 @@ void map_base::_set(const char *key, const void *value, void **oldvalue) } } } -void map_base::clear() -{ +void map_base::clear() { while (len) { delete[] ptr[--len].key; } @@ -79,3 +78,6 @@ void map_base::clear() ptr = 0; len = cap = 0; } +map_base::~map_base() { + clear(); +} diff --git a/src/map.hpp b/src/map.hpp index 3f26a96..77021c5 100644 --- a/src/map.hpp +++ b/src/map.hpp @@ -19,8 +19,12 @@ struct map_base { char *key; void *value; }; - map_value *ptr; - size_t len, cap; + map_value *ptr = 0; + size_t len = 0; + size_t cap = 0; + + map_base& operator=(map_base&&) = delete; + ~map_base(); /* Return the associated value for a given key. * Dynarr complexity: O(log n) */ void *_get(const char *key); -- 2.56.0