Prevent accidental RAIIdmem construction
This commit is contained in:
parent
425c4242c1
commit
7d166a70e0
|
@ -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>
|
||||
|
|
15
common/include/compiler-exchange.h
Normal file
15
common/include/compiler-exchange.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue