Prevent accidental RAIIdmem construction

This commit is contained in:
Kp 2014-09-07 21:23:03 +00:00
parent 425c4242c1
commit 7d166a70e0
4 changed files with 64 additions and 36 deletions

View file

@ -656,6 +656,15 @@ A *a(A &b) {
if not self.check_cxx11_addressof(context, text=f) and not self.check_boost_addressof(context, text=f):
raise SCons.Errors.StopError("C++ compiler does not support free function addressof().")
@_custom_test
def check_cxx14_exchange(self,context):
f = '''
#include "compiler-exchange.h"
int main(int argc,char**){
return exchange(argc, 5);
}
'''
self.Cxx14Compile(context, text=f, msg='for C++14 exchange', successflags={'CPPDEFINES' : ['DXX_HAVE_CXX14_EXCHANGE']})
@_custom_test
def check_cxx14_integer_sequence(self,context):
f = '''
#include <utility>

View file

@ -0,0 +1,15 @@
#pragma once
#include <utility> // for std::move or for std::exchange
#ifdef DXX_HAVE_CXX14_EXCHANGE
using std::exchange;
#else
template <typename T1, typename T2 = T1>
static inline T1 exchange(T1 &a, T2 &&b)
{
T1 t = std::move(a);
a = std::forward<T2>(b);
return t;
}
#endif

View file

@ -24,6 +24,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#ifdef __cplusplus
#include "dxxsconf.h"
#include "compiler-exchange.h"
#include "compiler-type_traits.h"
#define MEM_K 1.5 // Dynamic array growth factor
@ -57,22 +58,19 @@ static inline void mem_init(void)
#endif
template <typename T>
T *MALLOC(std::size_t count, const char *var, const char *file, unsigned line)
T *MALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
{
static_assert(tt::is_pod<T>::value, "MALLOC cannot allocate non-POD");
return reinterpret_cast<T *>(mem_malloc(count, var, file, line));
return r = reinterpret_cast<T *>(mem_malloc(count, var, file, line));
}
template <typename T>
T *CALLOC(std::size_t count, const char *var, const char *file, unsigned line)
T *CALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
{
static_assert(tt::is_pod<T>::value, "CALLOC cannot allocate non-POD");
return reinterpret_cast<T *>(mem_calloc(count, sizeof(T), var, file, line));
return r = reinterpret_cast<T *>(mem_calloc(count, sizeof(T), var, file, line));
}
#define MALLOC( var, type, count ) (var=MALLOC<type>((count)*sizeof(type),#var, __FILE__,__LINE__ ))
#define CALLOC( var, type, count ) (var=CALLOC<type>((count),#var, __FILE__,__LINE__ ))
#define d_malloc(size) mem_malloc((size),"Unknown", __FILE__,__LINE__ )
#define d_calloc(nmemb,size) mem_calloc((nmemb),(size),"Unknown", __FILE__,__LINE__ )
#define d_realloc(ptr,size) mem_realloc((ptr),(size),"Unknown", __FILE__,__LINE__ )
@ -87,47 +85,53 @@ static inline void d_free(T *&ptr)
class BaseRAIIdmem
{
BaseRAIIdmem(const BaseRAIIdmem&);
BaseRAIIdmem& operator=(const BaseRAIIdmem&);
protected:
void *p;
BaseRAIIdmem() : p(NULL) {}
BaseRAIIdmem(void *v) : p(v) {}
~BaseRAIIdmem() {
*this = NULL;
}
BaseRAIIdmem& operator=(void *v)
BaseRAIIdmem(const BaseRAIIdmem&) = delete;
BaseRAIIdmem& operator=(const BaseRAIIdmem&) = delete;
BaseRAIIdmem(BaseRAIIdmem &&that) : p(exchange(that.p, nullptr)) {}
BaseRAIIdmem& operator=(BaseRAIIdmem &&rhs)
{
if (p != v)
{
#ifdef DEBUG_MEMORY_ALLOCATIONS
if (p) // Avoid bogus warning about freeing NULL
#endif
d_free(p);
p = v;
}
std::swap(p, rhs.p);
return *this;
}
void *p;
BaseRAIIdmem(void *v = nullptr) : p(v) {}
~BaseRAIIdmem() {
#ifdef DEBUG_MEMORY_ALLOCATIONS
if (p) // Avoid bogus warning about freeing NULL
#endif
d_free(p);
}
};
template <typename T>
class RAIIdmem : public BaseRAIIdmem
struct RAIIdmem : BaseRAIIdmem
{
RAIIdmem(const RAIIdmem&);
RAIIdmem& operator=(const RAIIdmem&);
public:
static_assert(tt::is_pod<T>::value, "RAIIdmem cannot manage non-POD");
RAIIdmem() {}
RAIIdmem(T *v) : BaseRAIIdmem(v) {}
RAIIdmem() = default;
RAIIdmem(std::nullptr_t) : BaseRAIIdmem(nullptr) {}
explicit RAIIdmem(T *v) : BaseRAIIdmem(v) {}
operator T*() const { return static_cast<T*>(p); }
T *operator->() const { return static_cast<T*>(p); }
RAIIdmem& operator=(T *v)
{
BaseRAIIdmem::operator=(v);
return *this;
}
};
template <typename T>
T *MALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
{
T *p;
return r = RAIIdmem<T>(MALLOC<T>(p, count, var, file, line));
}
template <typename T>
T *CALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
{
T *p;
return r = RAIIdmem<T>(CALLOC<T>(p, count, var, file, line));
}
#define MALLOC( var, type, count ) (MALLOC<type>(var, (count)*sizeof(type),#var, __FILE__,__LINE__ ))
#define CALLOC( var, type, count ) (CALLOC<type>(var, (count),#var, __FILE__,__LINE__ ))
typedef RAIIdmem<unsigned char> RAIIdubyte;
typedef RAIIdmem<char> RAIIdchar;
#endif

View file

@ -76,7 +76,7 @@ UI_GADGET_RADIO * ui_add_gadget_radio( UI_DIALOG * dlg, short x, short y, short
{
auto radio = ui_gadget_add<UI_GADGET_RADIO>( dlg, x, y, x+w-1, y+h-1 );
radio->text = d_strdup(text);
radio->text = RAIIdmem<char>(d_strdup(text));
radio->width = w;
radio->height = h;
radio->position = 0;