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):
|
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().")
|
raise SCons.Errors.StopError("C++ compiler does not support free function addressof().")
|
||||||
@_custom_test
|
@_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):
|
def check_cxx14_integer_sequence(self,context):
|
||||||
f = '''
|
f = '''
|
||||||
#include <utility>
|
#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
|
#ifdef __cplusplus
|
||||||
#include "dxxsconf.h"
|
#include "dxxsconf.h"
|
||||||
|
#include "compiler-exchange.h"
|
||||||
#include "compiler-type_traits.h"
|
#include "compiler-type_traits.h"
|
||||||
|
|
||||||
#define MEM_K 1.5 // Dynamic array growth factor
|
#define MEM_K 1.5 // Dynamic array growth factor
|
||||||
|
@ -57,22 +58,19 @@ static inline void mem_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
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");
|
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>
|
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");
|
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_malloc(size) mem_malloc((size),"Unknown", __FILE__,__LINE__ )
|
||||||
#define d_calloc(nmemb,size) mem_calloc((nmemb),(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__ )
|
#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
|
class BaseRAIIdmem
|
||||||
{
|
{
|
||||||
BaseRAIIdmem(const BaseRAIIdmem&);
|
|
||||||
BaseRAIIdmem& operator=(const BaseRAIIdmem&);
|
|
||||||
protected:
|
protected:
|
||||||
void *p;
|
BaseRAIIdmem(const BaseRAIIdmem&) = delete;
|
||||||
BaseRAIIdmem() : p(NULL) {}
|
BaseRAIIdmem& operator=(const BaseRAIIdmem&) = delete;
|
||||||
BaseRAIIdmem(void *v) : p(v) {}
|
BaseRAIIdmem(BaseRAIIdmem &&that) : p(exchange(that.p, nullptr)) {}
|
||||||
~BaseRAIIdmem() {
|
BaseRAIIdmem& operator=(BaseRAIIdmem &&rhs)
|
||||||
*this = NULL;
|
{
|
||||||
|
std::swap(p, rhs.p);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
BaseRAIIdmem& operator=(void *v)
|
void *p;
|
||||||
{
|
BaseRAIIdmem(void *v = nullptr) : p(v) {}
|
||||||
if (p != v)
|
~BaseRAIIdmem() {
|
||||||
{
|
|
||||||
#ifdef DEBUG_MEMORY_ALLOCATIONS
|
#ifdef DEBUG_MEMORY_ALLOCATIONS
|
||||||
if (p) // Avoid bogus warning about freeing NULL
|
if (p) // Avoid bogus warning about freeing NULL
|
||||||
#endif
|
#endif
|
||||||
d_free(p);
|
d_free(p);
|
||||||
p = v;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
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");
|
static_assert(tt::is_pod<T>::value, "RAIIdmem cannot manage non-POD");
|
||||||
RAIIdmem() {}
|
RAIIdmem() = default;
|
||||||
RAIIdmem(T *v) : BaseRAIIdmem(v) {}
|
RAIIdmem(std::nullptr_t) : BaseRAIIdmem(nullptr) {}
|
||||||
|
explicit RAIIdmem(T *v) : BaseRAIIdmem(v) {}
|
||||||
operator T*() const { return static_cast<T*>(p); }
|
operator T*() const { return static_cast<T*>(p); }
|
||||||
T *operator->() 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<unsigned char> RAIIdubyte;
|
||||||
typedef RAIIdmem<char> RAIIdchar;
|
typedef RAIIdmem<char> RAIIdchar;
|
||||||
#endif
|
#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 );
|
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->width = w;
|
||||||
radio->height = h;
|
radio->height = h;
|
||||||
radio->position = 0;
|
radio->position = 0;
|
||||||
|
|
Loading…
Reference in a new issue