summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-06-11 21:55:13 -0700
committerBen Longbons <b.r.longbons@gmail.com>2013-06-11 23:27:33 -0700
commit8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13 (patch)
tree15e8a4841af992e17794f26fc7991ed40c35bd51 /src/common
parent8c6072df499ef9068346fbe8313b63dbba1e4e82 (diff)
downloadtmwa-8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13.tar.gz
tmwa-8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13.tar.bz2
tmwa-8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13.tar.xz
tmwa-8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13.zip
Allegedly remove all manual memory management
Diffstat (limited to 'src/common')
-rw-r--r--src/common/const_array.hpp38
-rw-r--r--src/common/core.cpp12
-rw-r--r--src/common/db.hpp69
-rw-r--r--src/common/dumb_ptr.hpp199
-rw-r--r--src/common/intern-pool.hpp35
-rw-r--r--src/common/matrix.hpp50
-rw-r--r--src/common/md5calc.cpp4
-rw-r--r--src/common/mmo.hpp2
-rw-r--r--src/common/socket.cpp51
-rw-r--r--src/common/utils.cpp2
-rw-r--r--src/common/utils.hpp34
-rw-r--r--src/common/utils2.hpp12
12 files changed, 435 insertions, 73 deletions
diff --git a/src/common/const_array.hpp b/src/common/const_array.hpp
index 93ae337..06045dc 100644
--- a/src/common/const_array.hpp
+++ b/src/common/const_array.hpp
@@ -70,55 +70,59 @@ public:
// but disallow conversion from a temporary
const_array(std::vector<T>&&) = delete;
- // All methods are non-const to "encourage" you
- // to always pass a const_array by value.
- // After all, "const const_array" looks funny.
+ // Oops. see src/warnings.hpp
constexpr
- const T *data() { return d; }
+ const T *data() const { return d; }
constexpr
- size_t size() { return n; }
+ size_t size() const { return n; }
constexpr
- bool empty() { return not n; }
+ bool empty() const { return not n; }
constexpr explicit
- operator bool() { return n; }
+ operator bool() const { return n; }
constexpr
- std::pair<const_array, const_array> cut(size_t o)
+ std::pair<const_array, const_array> cut(size_t o) const
{
return {const_array(d, o), const_array(d + o, n - o)};
}
constexpr
- const_array first(size_t o)
+ const_array first(size_t o) const
{
return cut(o).first;
}
constexpr
- const_array last(size_t l)
+ const_array last(size_t l) const
{
return cut(size() - l).second;
}
constexpr
- const_array after(size_t o)
+ const_array after(size_t o) const
{
return cut(o).second;
}
constexpr
- iterator begin() { return d; }
+ iterator begin() const { return d; }
constexpr
- iterator end() { return d + n; }
+ iterator end() const { return d + n; }
constexpr
- reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rbegin() const { return reverse_iterator(end()); }
constexpr
- reverse_iterator rend() { return reverse_iterator(begin()); }
+ reverse_iterator rend() const { return reverse_iterator(begin()); }
constexpr
- const T& front() { return *begin(); }
+ const T& front() const { return *begin(); }
constexpr
- const T& back() { return *rbegin(); }
+ const T& back() const { return *rbegin(); }
+
+ // This probably shouldn't be used, but I'm adding it for porting.
+ T& operator[](size_t i)
+ {
+ return const_cast<T&>(d[i]);
+ }
};
// subclass just provides a simpler name and some conversions
diff --git a/src/common/core.cpp b/src/common/core.cpp
index 994de93..153414d 100644
--- a/src/common/core.cpp
+++ b/src/common/core.cpp
@@ -36,7 +36,10 @@ sigfunc compat_signal(int signo, sigfunc func)
sact.sa_flags = 0;
if (sigaction(signo, &sact, &oact) < 0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
return SIG_ERR;
+#pragma GCC diagnostic pop
return oact.sa_handler;
}
@@ -50,7 +53,10 @@ static __attribute__((noreturn))
void sig_proc(int)
{
for (int i = 1; i < 31; ++i)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
compat_signal(i, SIG_IGN);
+#pragma GCC diagnostic pop
term_func();
_exit(0);
}
@@ -74,17 +80,23 @@ int main(int argc, char **argv)
// set up exit handlers *after* the initialization has happened.
// This is because term_func is likely to depend on successful init.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
compat_signal(SIGPIPE, SIG_IGN);
+#pragma GCC diagnostic pop
compat_signal(SIGTERM, sig_proc);
compat_signal(SIGINT, sig_proc);
compat_signal(SIGCHLD, chld_proc);
// Signal to create coredumps by system when necessary (crash)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
compat_signal(SIGSEGV, SIG_DFL);
compat_signal(SIGBUS, SIG_DFL);
compat_signal(SIGTRAP, SIG_DFL);
compat_signal(SIGILL, SIG_DFL);
compat_signal(SIGFPE, SIG_DFL);
+#pragma GCC diagnostic pop
atexit(term_func);
diff --git a/src/common/db.hpp b/src/common/db.hpp
index bd47928..927db22 100644
--- a/src/common/db.hpp
+++ b/src/common/db.hpp
@@ -22,6 +22,7 @@
# include "sanity.hpp"
# include <map>
+# include <memory>
template<class K, class V>
class Map
@@ -56,7 +57,7 @@ public:
return nullptr;
return &it->second;
}
- void insert(K k, V v)
+ void insert(const K& k, V v)
{
// As far as I can tell, this is the simplest way to
// implement move-only insert-with-replacement.
@@ -69,7 +70,7 @@ public:
return (void)&it->second;
}
- V *init(K k)
+ V *init(const K& k)
{
return &impl[k];
}
@@ -81,10 +82,14 @@ public:
{
impl.clear();
}
- bool empty()
+ bool empty() const
{
return impl.empty();
}
+ size_t size() const
+ {
+ return impl.size();
+ }
};
template<class K, class V>
@@ -102,22 +107,74 @@ public:
const_iterator begin() const { return impl.begin(); }
const_iterator end() const { return impl.end(); }
- V get(K k)
+ // const V& ? with a static default V?
+ V get(const K& k)
{
V *vp = impl.search(k);
return vp ? *vp : V();
}
- void put(K k, V v)
+ void put(const K& k, V v)
{
if (v == V())
impl.erase(k);
else
- impl.insert(k, v);
+ impl.insert(k, std::move(v));
}
void clear()
{
impl.clear();
}
+ bool empty() const
+ {
+ return impl.empty();
+ }
+ size_t size() const
+ {
+ return impl.size();
+ }
+};
+
+template<class K, class V>
+class UPMap
+{
+ typedef std::unique_ptr<V> U;
+ typedef Map<K, U> Impl;
+
+ Impl impl;
+public:
+ typedef typename Impl::iterator iterator;
+ typedef typename Impl::const_iterator const_iterator;
+
+ iterator begin() { return impl.begin(); }
+ iterator end() { return impl.end(); }
+ const_iterator begin() const { return impl.begin(); }
+ const_iterator end() const { return impl.end(); }
+
+ // const V& ? with a static default V?
+ V *get(const K& k)
+ {
+ U *up = impl.search(k);
+ return up ? up->get() : nullptr;
+ }
+ void put(const K& k, U v)
+ {
+ if (!v)
+ impl.erase(k);
+ else
+ impl.insert(k, std::move(v));
+ }
+ void clear()
+ {
+ impl.clear();
+ }
+ bool empty() const
+ {
+ return impl.empty();
+ }
+ size_t size() const
+ {
+ return impl.size();
+ }
};
#endif // DB_HPP
diff --git a/src/common/dumb_ptr.hpp b/src/common/dumb_ptr.hpp
index 1a0b4a1..e10ca3a 100644
--- a/src/common/dumb_ptr.hpp
+++ b/src/common/dumb_ptr.hpp
@@ -21,8 +21,12 @@
#include "sanity.hpp"
+#include <cstring>
+
#include <algorithm>
+#include "const_array.hpp"
+
// unmanaged new/delete-able pointer
// should be replaced by std::unique_ptr<T>
template<class T>
@@ -176,4 +180,199 @@ public:
}
};
+struct dumb_string
+{
+ dumb_ptr<char[]> impl;
+
+ dumb_string()
+ : impl()
+ {}
+ dumb_string(char *) = delete;
+ // copy ctor, copy assign, and dtor are all default
+
+ static dumb_string copy(const char *b, const char *e)
+ {
+ dumb_string rv;
+ rv.impl.new_((e - b) + 1);
+ std::copy(b, e, &rv.impl[0]);
+ return rv;
+ }
+ static dumb_string copy(const char *sz)
+ {
+ return dumb_string::copy(sz, sz + strlen(sz));
+ }
+ static dumb_string copys(const std::string& s)
+ {
+ return dumb_string::copy(&*s.begin(), &*s.end());
+ }
+ static dumb_string copyn(const char *sn, size_t n)
+ {
+ return dumb_string::copy(sn, sn + strnlen(sn, n));
+ }
+ static dumb_string copyc(const_string s)
+ {
+ return dumb_string::copy(s.begin(), s.end());
+ }
+
+ static
+ dumb_string fake(const char *p)
+ {
+ dumb_string rv;
+ rv.impl = dumb_ptr<char[]>(const_cast<char *>(p), strlen(p));
+ return rv;
+ }
+
+ dumb_string dup() const
+ {
+ return dumb_string::copy(&impl[0]);
+ }
+ void delete_()
+ {
+ impl.delete_();
+ }
+
+ const char *c_str() const
+ {
+ return &impl[0];
+ }
+
+ std::string str() const
+ {
+ return c_str();
+ }
+
+ operator const_string() const
+ {
+ return const_string(c_str());
+ }
+
+ char& operator[](size_t i) const
+ {
+ return impl[i];
+ }
+
+ explicit
+ operator bool() const
+ {
+ return bool(impl);
+ }
+ bool operator !() const
+ {
+ return !impl;
+ }
+
+#if 0
+ friend bool operator == (dumb_string l, dumb_string r)
+ {
+ return l.impl == r.impl;
+ }
+ friend bool operator != (dumb_string l, dumb_string r)
+ {
+ return !(l == r);
+ }
+#endif
+};
+
+namespace operators
+{
+ inline
+ bool operator == (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) == 0;
+ }
+ inline
+ bool operator != (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) != 0;
+ }
+ inline
+ bool operator < (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) < 0;
+ }
+ inline
+ bool operator <= (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) <= 0;
+ }
+ inline
+ bool operator > (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) > 0;
+ }
+ inline
+ bool operator >= (dumb_string l, dumb_string r)
+ {
+ return strcmp(l.c_str(), r.c_str()) >= 0;
+ }
+
+ inline
+ bool operator == (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) == 0;
+ }
+ inline
+ bool operator != (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) != 0;
+ }
+ inline
+ bool operator < (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) < 0;
+ }
+ inline
+ bool operator <= (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) <= 0;
+ }
+ inline
+ bool operator > (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) > 0;
+ }
+ inline
+ bool operator >= (const char *l, dumb_string r)
+ {
+ return strcmp(l, r.c_str()) >= 0;
+ }
+
+ inline
+ bool operator == (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) == 0;
+ }
+ inline
+ bool operator != (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) != 0;
+ }
+ inline
+ bool operator < (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) < 0;
+ }
+ inline
+ bool operator <= (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) <= 0;
+ }
+ inline
+ bool operator > (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) > 0;
+ }
+ inline
+ bool operator >= (dumb_string l, const char *r)
+ {
+ return strcmp(l.c_str(), r) >= 0;
+ }
+}
+
+inline
+const char *convert_for_printf(dumb_string ds)
+{
+ return ds.c_str();
+}
+
#endif // TMWA_COMMON_DUMB_PTR_HPP
diff --git a/src/common/intern-pool.hpp b/src/common/intern-pool.hpp
new file mode 100644
index 0000000..caa54e4
--- /dev/null
+++ b/src/common/intern-pool.hpp
@@ -0,0 +1,35 @@
+#ifndef INTERN_POOL_HPP
+#define INTERN_POOL_HPP
+
+#include <cassert>
+
+#include <map>
+#include <string>
+#include <vector>
+
+class InternPool
+{
+ std::map<std::string, size_t> known;
+ std::vector<std::string> names;
+public:
+ size_t intern(const std::string& name)
+ {
+ auto pair = known.insert({name, known.size()});
+ if (pair.second)
+ names.push_back(name);
+ assert (known.size() == names.size());
+ return pair.first->second;
+ }
+
+ const std::string& outtern(size_t sz) const
+ {
+ return names[sz];
+ }
+
+ size_t size() const
+ {
+ return known.size();
+ }
+};
+
+#endif //INTERN_POOL_HPP
diff --git a/src/common/matrix.hpp b/src/common/matrix.hpp
new file mode 100644
index 0000000..8595191
--- /dev/null
+++ b/src/common/matrix.hpp
@@ -0,0 +1,50 @@
+#ifndef TMWA_COMMON_MATRIX_HPP
+#define TMWA_COMMON_MATRIX_HPP
+
+template<class T>
+class Matrix
+{
+ std::unique_ptr<T[]> _data;
+ size_t _xs, _ys;
+public:
+ Matrix()
+ : _data()
+ , _xs()
+ , _ys()
+ {}
+ Matrix(size_t x, size_t y)
+ : _data(new T[x * y]())
+ , _xs(x)
+ , _ys(y)
+ {}
+ // no copy-ctor or copy-assign
+
+ void reset(size_t x, size_t y)
+ {
+ *this = Matrix(x, y);
+ }
+ void clear()
+ {
+ *this = Matrix();
+ }
+
+ T& ref(size_t x, size_t y)
+ {
+ return _data[x + y * _xs];
+ }
+ const T& ref(size_t x, size_t y) const
+ {
+ return _data[x + y * _xs];
+ }
+
+ size_t xs() const
+ {
+ return _xs;
+ }
+ size_t ys() const
+ {
+ return _ys;
+ }
+};
+
+#endif // TMWA_COMMON_MATRIX_HPP
diff --git a/src/common/md5calc.cpp b/src/common/md5calc.cpp
index 1625912..36f220d 100644
--- a/src/common/md5calc.cpp
+++ b/src/common/md5calc.cpp
@@ -210,7 +210,7 @@ MD5_state MD5_from_string(const char* msg, const size_t msglen)
if (64 - rem > 8)
{
for (int i=0; i<8; i++)
- buf[0x38+i] = ((uint64_t)msglen*8) >> (i*8);
+ buf[0x38+i] = (static_cast<uint64_t>(msglen)*8) >> (i*8);
}
for (int i=0; i<0x10; i++)
X[i] = buf[4*i+0] | buf[4*i+1]<<8 | buf[4*i+2]<<16 | buf[4*i+3]<<24;
@@ -219,7 +219,7 @@ MD5_state MD5_from_string(const char* msg, const size_t msglen)
{
memset(buf,'\0', 0x38);
for (int i=0; i<8; i++)
- buf[0x38+i] = ((uint64_t)msglen*8) >> (i*8);
+ buf[0x38+i] = (static_cast<uint64_t>(msglen)*8) >> (i*8);
for (int i=0; i<0x10; i++)
X[i] = buf[4*i+0] | buf[4*i+1]<<8 | buf[4*i+2]<<16 | buf[4*i+3]<<24;
MD5_do_block(&state, block);
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index e72bf80..a04fd34 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -206,7 +206,7 @@ struct map_session_data;
struct GM_Account
{
int account_id;
- int level;
+ uint8_t level;
};
struct party_member
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
index db944cc..0ee8712 100644
--- a/src/common/socket.cpp
+++ b/src/common/socket.cpp
@@ -29,7 +29,10 @@ const uint32_t RFIFO_SIZE = 65536;
static
const uint32_t WFIFO_SIZE = 65536;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
std::array<std::unique_ptr<struct socket_data>, FD_SETSIZE> session;
+#pragma GCC diagnostic pop
/// clean up by discarding handled bytes
inline
@@ -119,7 +122,7 @@ void connect_client(int listen_fd)
struct sockaddr_in client_address;
socklen_t len = sizeof(client_address);
- int fd = accept(listen_fd, (struct sockaddr *) &client_address, &len);
+ int fd = accept(listen_fd, reinterpret_cast<struct sockaddr *>(&client_address), &len);
if (fd == -1)
{
perror("accept");
@@ -156,11 +159,14 @@ void connect_client(int listen_fd)
setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof yes);
#endif
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_SET(fd, &readfds);
+#pragma GCC diagnostic pop
fcntl(fd, F_SETFL, O_NONBLOCK);
- session[fd].reset(new socket_data());
+ session[fd] = make_unique<socket_data>();
session[fd]->rdata.new_(RFIFO_SIZE);
session[fd]->wdata.new_(WFIFO_SIZE);
@@ -202,10 +208,13 @@ int make_listen_port(uint16_t port)
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes);
server_address.sin_family = AF_INET;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(port);
+#pragma GCC diagnostic pop
- if (bind(fd, (struct sockaddr *) &server_address,
+ if (bind(fd, reinterpret_cast<struct sockaddr *>(&server_address),
sizeof(server_address)) == -1)
{
perror("bind");
@@ -217,9 +226,12 @@ int make_listen_port(uint16_t port)
exit(1);
}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_SET(fd, &readfds);
+#pragma GCC diagnostic pop
- session[fd].reset(new socket_data());
+ session[fd] = make_unique<socket_data>();
session[fd]->func_recv = connect_client;
session[fd]->created = TimeT::now();
@@ -254,18 +266,24 @@ int make_connection(uint32_t ip, uint16_t port)
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = ip;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
server_address.sin_port = htons(port);
+#pragma GCC diagnostic pop
fcntl(fd, F_SETFL, O_NONBLOCK);
/// Errors not caught - we must not block
/// Let the main select() loop detect when we know the state
- connect(fd, (struct sockaddr *) &server_address,
+ connect(fd, reinterpret_cast<struct sockaddr *>(&server_address),
sizeof(struct sockaddr_in));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_SET(fd, &readfds);
+#pragma GCC diagnostic pop
- session[fd].reset(new socket_data());
+ session[fd] = make_unique<socket_data>();
session[fd]->rdata.new_(RFIFO_SIZE);
session[fd]->wdata.new_(WFIFO_SIZE);
@@ -283,14 +301,20 @@ int make_connection(uint32_t ip, uint16_t port)
void delete_session(int fd)
{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
if (fd < 0 || fd >= FD_SETSIZE)
+#pragma GCC diagnostic pop
return;
// If this was the highest fd, decrease it
// We could add a loop to decrement fd_max further for every null session,
// but this is cheap and good enough for the typical case
if (fd == fd_max - 1)
fd_max--;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_CLR(fd, &readfds);
+#pragma GCC diagnostic pop
if (session[fd])
{
session[fd]->rdata.delete_();
@@ -343,11 +367,17 @@ void WFIFOSET(int fd, size_t len)
void do_sendrecv(interval_t next_ms)
{
fd_set rfd = readfds, wfd;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_ZERO(&wfd);
+#pragma GCC diagnostic pop
for (int i = 0; i < fd_max; i++)
{
if (session[i] && session[i]->wdata_size)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_SET(i, &wfd);
+#pragma GCC diagnostic pop
}
struct timeval timeout;
{
@@ -362,13 +392,19 @@ void do_sendrecv(interval_t next_ms)
{
if (!session[i])
continue;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
if (FD_ISSET(i, &wfd))
+#pragma GCC diagnostic pop
{
if (session[i]->func_send)
//send_from_fifo(i);
session[i]->func_send(i);
}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
if (FD_ISSET(i, &rfd))
+#pragma GCC diagnostic pop
{
if (session[i]->func_recv)
//recv_to_fifo(i);
@@ -406,7 +442,10 @@ void do_parsepacket(void)
void do_socket(void)
{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
FD_ZERO(&readfds);
+#pragma GCC diagnostic pop
currentuse = 3;
}
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index e3867eb..4e00808 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -87,7 +87,7 @@ int config_switch (const char *str)
const char *ip2str(struct in_addr ip, bool extra_dot)
{
- const uint8_t *p = (const uint8_t *)(&ip);
+ const uint8_t *p = reinterpret_cast<const uint8_t *>(&ip);
static char buf[17];
if (extra_dot)
sprintf(buf, "%d.%d.%d.%d.", p[0], p[1], p[2], p[3]);
diff --git a/src/common/utils.hpp b/src/common/utils.hpp
index f2a2117..caa39ed 100644
--- a/src/common/utils.hpp
+++ b/src/common/utils.hpp
@@ -12,40 +12,6 @@
#include "operators.hpp"
#include "utils2.hpp"
-/*
-Notes about memory allocation in tmwAthena:
-There used to be 3 sources of allocation: these macros,
-a{C,M,Re}alloc in common/malloc.{h,c}, and direct calls.
-I deleted malloc.{h,c} because it was redundant;
-future calls should either use this or depend on the coming segfault.
-*/
-template<class T>
-void create_impl(T *& result, size_t number)
-{
- result = (T *)calloc(number, sizeof(T));
- if (!result && number)
- {
- perror("SYSERR: malloc failure");
- abort();
- }
-}
-template<class T>
-void recreate_impl(T *& result, size_t number)
-{
- result = (T *)realloc(result, sizeof(T) * number);
- if (!result && number)
- {
- perror("SYSERR: realloc failure");
- abort();
- }
-}
-
-# define CREATE(result, type, number) \
- create_impl<type>(result, number)
-
-# define RECREATE(result, type, number) \
- recreate_impl<type>(result, number)
-
int remove_control_chars(char *str);
int e_mail_check(const char *email);
int config_switch (const char *str);
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
index 5f02beb..2218625 100644
--- a/src/common/utils2.hpp
+++ b/src/common/utils2.hpp
@@ -214,17 +214,17 @@ struct is_array_of_unknown_bound
: std::is_same<T, typename std::remove_extent<T>::type[]>
{};
-template<class T, class... A>
-typename std::enable_if<!is_array_of_unknown_bound<T>::value, std::unique_ptr<T>>::type make_unique(A&&... a)
+template<class T, class D=std::default_delete<T>, class... A>
+typename std::enable_if<!is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(A&&... a)
{
- return std::unique_ptr<T>(new T(a...));
+ return std::unique_ptr<T, D>(new T(a...));
}
-template<class T>
-typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T>>::type make_unique(size_t sz)
+template<class T, class D=std::default_delete<T>>
+typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(size_t sz)
{
typedef typename std::remove_extent<T>::type E;
- return std::unique_ptr<E[]>(new E[sz]);
+ return std::unique_ptr<E[], D>(new E[sz]());
}
#endif // UTILS2_HPP