resolved an oversight past me never realized where you still need to call destructors on placement new'd memory (and other things to resolve a memory leak that was very noticeable with 16MB of RAM)
This commit is contained in:
parent
9858cf9800
commit
5f8a80c25f
@ -76,10 +76,10 @@
|
|||||||
"shadows": true
|
"shadows": true
|
||||||
},
|
},
|
||||||
"stream": {
|
"stream": {
|
||||||
"tag": "", // worldspawn",
|
"tag": "worldspawn",
|
||||||
"player": "info_player_spawn",
|
"player": "info_player_spawn",
|
||||||
"enabled": true, // "auto",
|
"enabled": "auto",
|
||||||
"radius": 16,
|
"radius": 32,
|
||||||
"every": 1
|
"every": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,7 @@ size_t uf::Object::addHook( const uf::stl::string& name, T callback ) {
|
|||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uf::Hooks::return_t uf::Object::callHook( const uf::stl::string& name, const T& p ) {
|
uf::Hooks::return_t uf::Object::callHook( const uf::stl::string& name, const T& p ) {
|
||||||
pod::Hook::userdata_t payload;
|
return uf::hooks.call( this->formatHookName( name ), p );
|
||||||
payload.create<T>(p);
|
|
||||||
|
|
||||||
return uf::hooks.call( this->formatHookName( name ), payload );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -34,8 +34,15 @@ size_t uf::Hooks::addHook( const uf::Hooks::name_t& name, const Function& lambda
|
|||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uf::Hooks::return_t uf::Hooks::call( const uf::Hooks::name_t& name, const T& p ) {
|
uf::Hooks::return_t uf::Hooks::call( const uf::Hooks::name_t& name, const T& p ) {
|
||||||
|
// alias directly to save an allocation
|
||||||
|
pod::Hook::userdata_t payload;
|
||||||
|
payload.alias<T>(const_cast<T&>(p));
|
||||||
|
return call( name, payload );
|
||||||
|
/*
|
||||||
pod::Hook::userdata_t payload;
|
pod::Hook::userdata_t payload;
|
||||||
payload.create<T>(p);
|
payload.create<T>(p);
|
||||||
|
auto results = call( name, payload );
|
||||||
return call( name, payload );
|
payload.destruct<T>();
|
||||||
|
return results;
|
||||||
|
*/
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ namespace pod {
|
|||||||
|
|
||||||
namespace uf {
|
namespace uf {
|
||||||
namespace pointeredUserdata {
|
namespace pointeredUserdata {
|
||||||
pod::PointeredUserdata UF_API create( size_t len, void* data = NULL );
|
pod::PointeredUserdata UF_API create( size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
void UF_API destroy( pod::PointeredUserdata& userdata );
|
void UF_API destroy( pod::PointeredUserdata& userdata );
|
||||||
pod::PointeredUserdata UF_API copy( const pod::PointeredUserdata& userdata );
|
pod::PointeredUserdata UF_API copy( const pod::PointeredUserdata& userdata );
|
||||||
|
|
||||||
@ -17,15 +17,19 @@ namespace uf {
|
|||||||
template<typename T> const T& get(const pod::PointeredUserdata& userdata, bool validate = uf::userdata::autoValidate );
|
template<typename T> const T& get(const pod::PointeredUserdata& userdata, bool validate = uf::userdata::autoValidate );
|
||||||
template<typename T> bool is(const pod::PointeredUserdata& userdata);
|
template<typename T> bool is(const pod::PointeredUserdata& userdata);
|
||||||
|
|
||||||
|
|
||||||
uf::stl::string UF_API toBase64( pod::PointeredUserdata& userdata );
|
uf::stl::string UF_API toBase64( pod::PointeredUserdata& userdata );
|
||||||
pod::PointeredUserdata UF_API fromBase64( const uf::stl::string& base64 );
|
pod::PointeredUserdata UF_API fromBase64( const uf::stl::string& base64 );
|
||||||
|
|
||||||
// usage with MemoryPool
|
// usage with MemoryPool
|
||||||
pod::PointeredUserdata UF_API create( uf::MemoryPool&, size_t len, void* data = NULL );
|
pod::PointeredUserdata UF_API create( uf::MemoryPool&, size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
template<typename T> pod::PointeredUserdata create( uf::MemoryPool&, const T& data = T() );
|
template<typename T> pod::PointeredUserdata create( uf::MemoryPool&, const T& data = T() );
|
||||||
void UF_API destroy( uf::MemoryPool&, pod::PointeredUserdata& userdata );
|
void UF_API destroy( uf::MemoryPool&, pod::PointeredUserdata& userdata );
|
||||||
pod::PointeredUserdata UF_API copy( uf::MemoryPool&, const pod::PointeredUserdata& userdata );
|
pod::PointeredUserdata UF_API copy( uf::MemoryPool&, const pod::PointeredUserdata& userdata );
|
||||||
|
|
||||||
|
const pod::UserdataTraits& UF_API getTrait( UF_USERDATA_CTTI_TYPE type );
|
||||||
|
template<typename T> const pod::UserdataTraits& registerTrait();
|
||||||
|
|
||||||
size_t UF_API size( size_t size, size_t padding = 0 );
|
size_t UF_API size( size_t size, size_t padding = 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,12 +47,12 @@ namespace uf {
|
|||||||
public:
|
public:
|
||||||
// C-tor
|
// C-tor
|
||||||
|
|
||||||
PointeredUserdata( size_t len = 0, void* data = NULL); // initializes POD to default
|
PointeredUserdata( size_t len = 0, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void)); // initializes POD to default
|
||||||
PointeredUserdata( const pod::PointeredUserdata& ); // initializes from POD
|
PointeredUserdata( const pod::PointeredUserdata& ); // initializes from POD
|
||||||
PointeredUserdata( PointeredUserdata&& move ) noexcept; // Move c-tor
|
PointeredUserdata( PointeredUserdata&& move ) noexcept; // Move c-tor
|
||||||
PointeredUserdata( const PointeredUserdata& copy ); // Copy c-tor
|
PointeredUserdata( const PointeredUserdata& copy ); // Copy c-tor
|
||||||
|
|
||||||
pod::PointeredUserdata& create( size_t len, void* data = NULL );
|
pod::PointeredUserdata& create( size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
void move( PointeredUserdata& move );
|
void move( PointeredUserdata& move );
|
||||||
void move( PointeredUserdata&& move );
|
void move( PointeredUserdata&& move );
|
||||||
void copy( const PointeredUserdata& copy );
|
void copy( const PointeredUserdata& copy );
|
||||||
@ -70,13 +74,15 @@ namespace uf {
|
|||||||
template<typename T> bool is() const;
|
template<typename T> bool is() const;
|
||||||
template<typename T> inline T& as() { return get<T>(); }
|
template<typename T> inline T& as() { return get<T>(); }
|
||||||
template<typename T> inline const T& as() const { return get<T>(); }
|
template<typename T> inline const T& as() const { return get<T>(); }
|
||||||
|
|
||||||
|
template<typename T> void alias( T& );
|
||||||
// Overloaded ops
|
// Overloaded ops
|
||||||
operator void*();
|
operator void*();
|
||||||
operator void*() const;
|
operator void*() const;
|
||||||
|
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
|
|
||||||
PointeredUserdata& operator=( pod::PointeredUserdata pointer );
|
PointeredUserdata& operator=( const pod::PointeredUserdata& pointer );
|
||||||
PointeredUserdata& operator=( PointeredUserdata&& move );
|
PointeredUserdata& operator=( PointeredUserdata&& move );
|
||||||
PointeredUserdata& operator=( const PointeredUserdata& copy );
|
PointeredUserdata& operator=( const PointeredUserdata& copy );
|
||||||
};
|
};
|
||||||
@ -90,15 +96,8 @@ pod::PointeredUserdata uf::pointeredUserdata::create( const T& data ) {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
pod::PointeredUserdata uf::pointeredUserdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
|
pod::PointeredUserdata uf::pointeredUserdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
|
||||||
// if ( std::is_reference<T>() ) return uf::pointeredUserdata::create<typename std::remove_reference<T>::type>( requestedMemoryPool, data );
|
// if ( std::is_reference<T>() ) return uf::pointeredUserdata::create<typename std::remove_reference<T>::type>( requestedMemoryPool, data );
|
||||||
pod::PointeredUserdata userdata = uf::pointeredUserdata::create( requestedMemoryPool, sizeof(data), nullptr );
|
uf::pointeredUserdata::registerTrait<T>();
|
||||||
userdata.type = UF_USERDATA_CTTI(T);
|
return uf::pointeredUserdata::create( requestedMemoryPool, sizeof(data), (const void*) &data, UF_USERDATA_CTTI(T) );
|
||||||
union {
|
|
||||||
void* from;
|
|
||||||
T* to;
|
|
||||||
} kludge;
|
|
||||||
kludge.from = userdata.data;
|
|
||||||
::new (kludge.to) T(data);
|
|
||||||
return userdata;
|
|
||||||
}
|
}
|
||||||
// Easy way to get the userdata as a reference
|
// Easy way to get the userdata as a reference
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -134,11 +133,16 @@ bool uf::pointeredUserdata::is( const pod::PointeredUserdata& userdata ) {
|
|||||||
if ( userdata.type != UF_USERDATA_CTTI(void) ) return userdata.type == UF_USERDATA_CTTI(T) && userdata.len == sizeof(T);
|
if ( userdata.type != UF_USERDATA_CTTI(void) ) return userdata.type == UF_USERDATA_CTTI(T) && userdata.len == sizeof(T);
|
||||||
return userdata.len == sizeof(T);
|
return userdata.len == sizeof(T);
|
||||||
}
|
}
|
||||||
|
template<typename T> const pod::UserdataTraits& uf::pointeredUserdata::registerTrait() {
|
||||||
|
auto& trait = uf::userdata::traits[UF_USERDATA_CTTI(T)];
|
||||||
|
trait.name = TYPE_NAME(T);
|
||||||
|
trait.constructor = &uf::userdata::construct<T>;
|
||||||
|
trait.destructor = &uf::userdata::destruct<T>;
|
||||||
|
return trait;}
|
||||||
|
//
|
||||||
// No need to cast data to a pointer AND get the data's size!
|
// No need to cast data to a pointer AND get the data's size!
|
||||||
template<typename T>
|
template<typename T>
|
||||||
pod::PointeredUserdata& uf::PointeredUserdata::create( const T& data ) {
|
pod::PointeredUserdata& uf::PointeredUserdata::create( const T& data ) {
|
||||||
this->destroy();
|
|
||||||
return this->m_pod = uf::pointeredUserdata::create<T>(data);
|
return this->m_pod = uf::pointeredUserdata::create<T>(data);
|
||||||
}
|
}
|
||||||
// Easy way to get the userdata as a reference
|
// Easy way to get the userdata as a reference
|
||||||
@ -155,4 +159,13 @@ const T& uf::PointeredUserdata::get(bool validate) const {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool uf::PointeredUserdata::is() const {
|
bool uf::PointeredUserdata::is() const {
|
||||||
return uf::pointeredUserdata::is<T>( this->m_pod );
|
return uf::pointeredUserdata::is<T>( this->m_pod );
|
||||||
|
}
|
||||||
|
|
||||||
|
// I am not proud of having to do this
|
||||||
|
template<typename T>
|
||||||
|
void uf::PointeredUserdata::alias( T& data ) {
|
||||||
|
autoDestruct = false;
|
||||||
|
m_pod.len = sizeof(T);
|
||||||
|
m_pod.data = (void*) &data;
|
||||||
|
m_pod.type = UF_USERDATA_CTTI(T);
|
||||||
}
|
}
|
@ -7,6 +7,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <uf/utils/memory/string.h>
|
#include <uf/utils/memory/string.h>
|
||||||
|
#include <uf/utils/memory/unordered_map.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
|
|
||||||
@ -22,15 +23,23 @@ namespace pod {
|
|||||||
UF_USERDATA_CTTI_TYPE type = UF_USERDATA_CTTI(void);
|
UF_USERDATA_CTTI_TYPE type = UF_USERDATA_CTTI(void);
|
||||||
uint8_t data[1];
|
uint8_t data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UF_API UserdataTraits {
|
||||||
|
uf::stl::string name = "";
|
||||||
|
void (*constructor)(void*, const void*) = NULL;
|
||||||
|
void (*destructor)(void*) = NULL;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace uf {
|
namespace uf {
|
||||||
namespace userdata {
|
namespace userdata {
|
||||||
|
extern UF_API uf::stl::unordered_map<UF_USERDATA_CTTI_TYPE, pod::UserdataTraits> traits;
|
||||||
|
|
||||||
extern UF_API uf::MemoryPool memoryPool;
|
extern UF_API uf::MemoryPool memoryPool;
|
||||||
extern UF_API bool autoDestruct;
|
extern UF_API bool autoDestruct;
|
||||||
extern UF_API bool autoValidate;
|
extern UF_API bool autoValidate;
|
||||||
|
|
||||||
pod::Userdata* UF_API create( size_t len, void* data = NULL );
|
pod::Userdata* UF_API create( size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
void UF_API destroy( pod::Userdata* userdata );
|
void UF_API destroy( pod::Userdata* userdata );
|
||||||
pod::Userdata* UF_API copy( const pod::Userdata* userdata );
|
pod::Userdata* UF_API copy( const pod::Userdata* userdata );
|
||||||
|
|
||||||
@ -46,12 +55,18 @@ namespace uf {
|
|||||||
// void copy( pod::Userdata& to, const pod::Userdata& from );
|
// void copy( pod::Userdata& to, const pod::Userdata& from );
|
||||||
|
|
||||||
// usage with MemoryPool
|
// usage with MemoryPool
|
||||||
pod::Userdata* UF_API create( uf::MemoryPool&, size_t len, void* data = NULL );
|
pod::Userdata* UF_API create( uf::MemoryPool&, size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
template<typename T> pod::Userdata* create( uf::MemoryPool&, const T& data = T() );
|
template<typename T> pod::Userdata* create( uf::MemoryPool&, const T& data = T() );
|
||||||
void UF_API destroy( uf::MemoryPool&, pod::Userdata* userdata );
|
void UF_API destroy( uf::MemoryPool&, pod::Userdata* userdata );
|
||||||
pod::Userdata* UF_API copy( uf::MemoryPool&, const pod::Userdata* userdata );
|
pod::Userdata* UF_API copy( uf::MemoryPool&, const pod::Userdata* userdata );
|
||||||
|
|
||||||
size_t UF_API size( size_t size, size_t padding = 0 );
|
size_t UF_API size( size_t size, size_t padding = 0 );
|
||||||
|
|
||||||
|
template<typename T> void construct( void* dst, const void* src );
|
||||||
|
template<typename T> void destruct( void* p );
|
||||||
|
|
||||||
|
const pod::UserdataTraits& UF_API getTrait( UF_USERDATA_CTTI_TYPE type );
|
||||||
|
template<typename T> const pod::UserdataTraits& registerTrait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +83,12 @@ namespace uf {
|
|||||||
public:
|
public:
|
||||||
// C-tor
|
// C-tor
|
||||||
|
|
||||||
Userdata( size_t len = 0, void* data = NULL ); // initializes POD to default
|
Userdata( size_t len = 0, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) ); // initializes POD to default
|
||||||
Userdata( pod::Userdata* ); // initializes from POD
|
Userdata( pod::Userdata* ); // initializes from POD
|
||||||
Userdata( Userdata&& move ) noexcept ; // Move c-tor
|
Userdata( Userdata&& move ) noexcept ; // Move c-tor
|
||||||
Userdata( const Userdata& copy ); // Copy c-tor
|
Userdata( const Userdata& copy ); // Copy c-tor
|
||||||
|
|
||||||
pod::Userdata* create( size_t len, void* data = NULL );
|
pod::Userdata* create( size_t len, const void* data = NULL, UF_USERDATA_CTTI_TYPE = UF_USERDATA_CTTI(void) );
|
||||||
void move( Userdata& move );
|
void move( Userdata& move );
|
||||||
void move( Userdata&& move );
|
void move( Userdata&& move );
|
||||||
void copy( const Userdata& copy );
|
void copy( const Userdata& copy );
|
||||||
|
@ -9,16 +9,9 @@ template<typename T>
|
|||||||
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
|
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
|
||||||
// CTTI information of a T& != T
|
// CTTI information of a T& != T
|
||||||
// if ( std::is_reference<T>() ) return uf::userdata::create<typename std::remove_reference<T>::type>( requestedMemoryPool, data );
|
// if ( std::is_reference<T>() ) return uf::userdata::create<typename std::remove_reference<T>::type>( requestedMemoryPool, data );
|
||||||
|
// Register trait
|
||||||
pod::Userdata* userdata = uf::userdata::create( requestedMemoryPool, sizeof(data), nullptr );
|
uf::userdata::registerTrait<T>();
|
||||||
userdata->type = UF_USERDATA_CTTI(T);
|
return uf::userdata::create( requestedMemoryPool, sizeof(data), (const void*) &data, UF_USERDATA_CTTI(T) );
|
||||||
union {
|
|
||||||
void* from;
|
|
||||||
T* to;
|
|
||||||
} kludge;
|
|
||||||
kludge.from = userdata->data;
|
|
||||||
::new (kludge.to) T(data);
|
|
||||||
return userdata;
|
|
||||||
}
|
}
|
||||||
// Easy way to get the userdata as a reference
|
// Easy way to get the userdata as a reference
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -55,6 +48,21 @@ bool uf::userdata::is( const pod::Userdata* userdata ) {
|
|||||||
return userdata && userdata->len == sizeof(T);
|
return userdata && userdata->len == sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> void uf::userdata::construct( void* dst, const void* src ) {
|
||||||
|
::new (dst) T(*static_cast<const T*>(src));
|
||||||
|
}
|
||||||
|
template<typename T> void uf::userdata::destruct( void* p ) {
|
||||||
|
static_cast<T*>(p)->~T();
|
||||||
|
}
|
||||||
|
template<typename T> const pod::UserdataTraits& uf::userdata::registerTrait() {
|
||||||
|
auto& trait = uf::userdata::traits[UF_USERDATA_CTTI(T)];
|
||||||
|
trait.name = TYPE_NAME(T);
|
||||||
|
trait.constructor = &uf::userdata::construct<T>;
|
||||||
|
trait.destructor = &uf::userdata::destruct<T>;
|
||||||
|
return trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// No need to cast data to a pointer AND get the data's size!
|
// No need to cast data to a pointer AND get the data's size!
|
||||||
template<typename T>
|
template<typename T>
|
||||||
pod::Userdata* uf::Userdata::create( const T& data ) {
|
pod::Userdata* uf::Userdata::create( const T& data ) {
|
||||||
|
@ -288,7 +288,10 @@ void uf::ObjectBehavior::tick( uf::Object& self ) {
|
|||||||
else unprocessed.emplace_back(q);
|
else unprocessed.emplace_back(q);
|
||||||
}
|
}
|
||||||
for ( auto& q : executeQueue ) {
|
for ( auto& q : executeQueue ) {
|
||||||
if ( q.type == 1 ) this->callHook( q.name, q.userdata );
|
if ( q.type == 1 ) {
|
||||||
|
this->callHook( q.name, q.userdata );
|
||||||
|
q.userdata.destroy();
|
||||||
|
}
|
||||||
else if ( q.type == -1 ) this->callHook( q.name, q.json );
|
else if ( q.type == -1 ) this->callHook( q.name, q.json );
|
||||||
else this->callHook( q.name );
|
else this->callHook( q.name );
|
||||||
}
|
}
|
||||||
|
@ -95,13 +95,6 @@ namespace binds {
|
|||||||
if ( type == "Metadata" ) {
|
if ( type == "Metadata" ) {
|
||||||
auto encoded = ext::lua::encode( value.as<sol::table>() );
|
auto encoded = ext::lua::encode( value.as<sol::table>() );
|
||||||
if ( encoded ) {
|
if ( encoded ) {
|
||||||
/*
|
|
||||||
self.callHook( "object:Serialize.%UID%" );
|
|
||||||
auto& metadata = self.getComponent<uf::Serializer>();
|
|
||||||
uf::stl::string str = encoded.value();
|
|
||||||
metadata.merge( str, false );
|
|
||||||
self.callHook( "object:Deserialize.%UID%" );
|
|
||||||
*/
|
|
||||||
uf::stl::string str = encoded.value();
|
uf::stl::string str = encoded.value();
|
||||||
ext::json::Value json;
|
ext::json::Value json;
|
||||||
ext::json::decode( json, str );
|
ext::json::decode( json, str );
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Constructs a pod::PointeredUserdata struct
|
// Constructs a pod::PointeredUserdata struct
|
||||||
pod::PointeredUserdata uf::pointeredUserdata::create( size_t len, void* data ) {
|
pod::PointeredUserdata uf::pointeredUserdata::create( size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
return uf::pointeredUserdata::create( uf::userdata::memoryPool, len, data );
|
return uf::pointeredUserdata::create( uf::userdata::memoryPool, len, data, type );
|
||||||
}
|
}
|
||||||
void uf::pointeredUserdata::destroy( pod::PointeredUserdata& userdata ) {
|
void uf::pointeredUserdata::destroy( pod::PointeredUserdata& userdata ) {
|
||||||
return uf::pointeredUserdata::destroy( uf::userdata::memoryPool, userdata );
|
return uf::pointeredUserdata::destroy( uf::userdata::memoryPool, userdata );
|
||||||
@ -20,31 +20,38 @@ size_t uf::pointeredUserdata::size( size_t len, size_t padding ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
pod::PointeredUserdata uf::pointeredUserdata::create( uf::MemoryPool& requestedMemoryPool, size_t len, void* data ) {
|
pod::PointeredUserdata uf::pointeredUserdata::create( uf::MemoryPool& requestedMemoryPool, size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
if ( len <= 0 ) return {};
|
if ( len <= 0 ) return {};
|
||||||
size_t requestedLen = size( len );
|
size_t requestedLen = size( len );
|
||||||
#if UF_MEMORYPOOL_INVALID_MALLOC
|
#if UF_MEMORYPOOL_INVALID_MALLOC
|
||||||
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
||||||
pod::PointeredUserdata userdata = {
|
pod::PointeredUserdata userdata = {
|
||||||
.len = requestedLen,
|
.len = requestedLen,
|
||||||
|
.type = type,
|
||||||
.data = memoryPool.alloc( requestedLen ),
|
.data = memoryPool.alloc( requestedLen ),
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
uf::MemoryPool* memoryPool = {};
|
uf::MemoryPool* memoryPool = NULL;
|
||||||
if ( requestedMemoryPool.size() > 0 ) memoryPool = &requestedMemoryPool;
|
if ( requestedMemoryPool.size() > 0 ) memoryPool = &requestedMemoryPool;
|
||||||
else if ( uf::memoryPool::global.size() > 0 ) memoryPool = &uf::memoryPool::global;
|
else if ( uf::memoryPool::global.size() > 0 ) memoryPool = &uf::memoryPool::global;
|
||||||
pod::PointeredUserdata userdata = {};
|
pod::PointeredUserdata userdata = {};
|
||||||
if ( memoryPool ) userdata.data = memoryPool->alloc( requestedLen );
|
if ( memoryPool ) userdata.data = memoryPool->alloc( requestedLen );
|
||||||
else userdata.data = uf::allocator::malloc_m( requestedLen ); // allocate data for the userdata struct, and then some
|
else userdata.data = uf::allocator::malloc_m( requestedLen ); // allocate data for the userdata struct, and then some
|
||||||
|
userdata.len = requestedLen;
|
||||||
|
userdata.type = type;
|
||||||
#endif
|
#endif
|
||||||
if ( data ) memcpy( userdata.data, data, len );
|
auto& trait = uf::pointeredUserdata::getTrait( userdata.type );
|
||||||
else memset( userdata.data, 0, len );
|
if ( data && userdata.type != UF_USERDATA_CTTI(void) ) trait.constructor( userdata.data, data );
|
||||||
userdata.len = len;
|
else if ( data ) memcpy( userdata.data, data, requestedLen );
|
||||||
userdata.type = UF_USERDATA_CTTI(void);
|
else memset( userdata.data, 0, requestedLen );
|
||||||
|
//UF_MSG_DEBUG("Calling create: {}: {}", trait.name, (void*) userdata.data);
|
||||||
return userdata;
|
return userdata;
|
||||||
}
|
}
|
||||||
void uf::pointeredUserdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::PointeredUserdata& userdata ) {
|
void uf::pointeredUserdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::PointeredUserdata& userdata ) {
|
||||||
if ( !userdata.data ) return;
|
if ( !userdata.data ) return;
|
||||||
|
auto& trait = uf::pointeredUserdata::getTrait( userdata.type );
|
||||||
|
if ( userdata.type != UF_USERDATA_CTTI(void) ) trait.destructor( userdata.data );
|
||||||
|
//UF_MSG_DEBUG("Calling destroy: {}: {}", trait.name, (void*) userdata.data);
|
||||||
#if UF_MEMORYPOOL_INVALID_FREE
|
#if UF_MEMORYPOOL_INVALID_FREE
|
||||||
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
||||||
memoryPool.free( userdata.data, size(userdata.len) );
|
memoryPool.free( userdata.data, size(userdata.len) );
|
||||||
@ -58,6 +65,7 @@ void uf::pointeredUserdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::P
|
|||||||
#endif
|
#endif
|
||||||
userdata.len = 0;
|
userdata.len = 0;
|
||||||
userdata.data = NULL;
|
userdata.data = NULL;
|
||||||
|
userdata.type = UF_USERDATA_CTTI(void);
|
||||||
}
|
}
|
||||||
pod::PointeredUserdata uf::pointeredUserdata::copy( uf::MemoryPool& requestedMemoryPool, const pod::PointeredUserdata& userdata ) {
|
pod::PointeredUserdata uf::pointeredUserdata::copy( uf::MemoryPool& requestedMemoryPool, const pod::PointeredUserdata& userdata ) {
|
||||||
if ( !userdata.data || userdata.len <= 0 ) return {};
|
if ( !userdata.data || userdata.len <= 0 ) return {};
|
||||||
@ -66,6 +74,10 @@ pod::PointeredUserdata uf::pointeredUserdata::copy( uf::MemoryPool& requestedMem
|
|||||||
return copied;
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pod::UserdataTraits& uf::pointeredUserdata::getTrait( UF_USERDATA_CTTI_TYPE type ) {
|
||||||
|
return uf::userdata::traits[type];
|
||||||
|
}
|
||||||
|
|
||||||
uf::stl::string uf::pointeredUserdata::toBase64( pod::PointeredUserdata& userdata ) {
|
uf::stl::string uf::pointeredUserdata::toBase64( pod::PointeredUserdata& userdata ) {
|
||||||
return uf::base64::encode( static_cast<uint8_t*>(userdata.data), userdata.len );
|
return uf::base64::encode( static_cast<uint8_t*>(userdata.data), userdata.len );
|
||||||
}
|
}
|
||||||
@ -76,19 +88,18 @@ pod::PointeredUserdata uf::pointeredUserdata::fromBase64( const uf::stl::string&
|
|||||||
// C-tor
|
// C-tor
|
||||||
|
|
||||||
// Initializes POD
|
// Initializes POD
|
||||||
uf::PointeredUserdata::PointeredUserdata(size_t len, void* data) : m_pod({}), autoDestruct(uf::userdata::autoDestruct) {
|
uf::PointeredUserdata::PointeredUserdata(size_t len, const void* data, UF_USERDATA_CTTI_TYPE type) : m_pod({}), autoDestruct(uf::userdata::autoDestruct) {
|
||||||
if ( len && data ) this->create(len, data);
|
if ( len && data ) this->create(len, data, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes from POD
|
// Initializes from POD
|
||||||
uf::PointeredUserdata::PointeredUserdata( const pod::PointeredUserdata& pointer ) : m_pod(pointer), autoDestruct(uf::userdata::autoDestruct) {
|
uf::PointeredUserdata::PointeredUserdata( const pod::PointeredUserdata& userdata ) : m_pod({}), autoDestruct(uf::userdata::autoDestruct) {
|
||||||
|
this->create( userdata.len, userdata.data, userdata.type );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move c-tor
|
// Move c-tor
|
||||||
uf::PointeredUserdata::PointeredUserdata( PointeredUserdata&& move ) noexcept :
|
uf::PointeredUserdata::PointeredUserdata( PointeredUserdata&& move ) noexcept : m_pod(move.m_pod), autoDestruct(move.autoDestruct) {
|
||||||
m_pod(std::move(move.m_pod)),
|
move.m_pod = {};
|
||||||
autoDestruct(move.autoDestruct) {
|
|
||||||
}
|
}
|
||||||
// Copy c-tor
|
// Copy c-tor
|
||||||
uf::PointeredUserdata::PointeredUserdata( const PointeredUserdata& userdata ) {
|
uf::PointeredUserdata::PointeredUserdata( const PointeredUserdata& userdata ) {
|
||||||
@ -97,37 +108,27 @@ uf::PointeredUserdata::PointeredUserdata( const PointeredUserdata& userdata ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates the POD
|
// Creates the POD
|
||||||
pod::PointeredUserdata& uf::PointeredUserdata::create( size_t len, void* data ) {
|
pod::PointeredUserdata& uf::PointeredUserdata::create( size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
if ( len <= 0 ) return this->m_pod;
|
if ( len <= 0 ) return this->m_pod;
|
||||||
this->destroy();
|
this->destroy();
|
||||||
return this->m_pod = uf::pointeredUserdata::create( len, data );
|
return this->m_pod = uf::pointeredUserdata::create( len, data, type );
|
||||||
}
|
}
|
||||||
void uf::PointeredUserdata::move( PointeredUserdata& moved ) {
|
void uf::PointeredUserdata::move( PointeredUserdata& moved ) {
|
||||||
// if ( this->m_pod && move.m_pod ) uf::pointeredUserdata::move( *this->m_pod, *move.m_pod );
|
// if ( this->m_pod && move.m_pod ) uf::pointeredUserdata::move( *this->m_pod, *move.m_pod );
|
||||||
this->destroy();
|
this->destroy();
|
||||||
this->m_pod = moved.m_pod;
|
this->m_pod = moved.m_pod;
|
||||||
moved.m_pod.len = 0;
|
moved.m_pod = {};
|
||||||
moved.m_pod.data = NULL;
|
|
||||||
}
|
}
|
||||||
void uf::PointeredUserdata::move( PointeredUserdata&& moved ) {
|
void uf::PointeredUserdata::move( PointeredUserdata&& moved ) {
|
||||||
// if ( this->m_pod && move.m_pod ) uf::pointeredUserdata::move( *this->m_pod, *move.m_pod );
|
// if ( this->m_pod && move.m_pod ) uf::pointeredUserdata::move( *this->m_pod, *move.m_pod );
|
||||||
this->destroy();
|
this->destroy();
|
||||||
this->m_pod = moved.m_pod;
|
this->m_pod = moved.m_pod;
|
||||||
moved.m_pod.len = 0;
|
moved.m_pod = {};
|
||||||
moved.m_pod.data = NULL;
|
|
||||||
}
|
}
|
||||||
void uf::PointeredUserdata::copy( const PointeredUserdata& userdata ) {
|
void uf::PointeredUserdata::copy( const PointeredUserdata& userdata ) {
|
||||||
if ( !userdata.m_pod.data || !userdata.m_pod.len ) return;
|
if ( !userdata.m_pod.data || !userdata.m_pod.len ) return;
|
||||||
this->destroy();
|
this->destroy();
|
||||||
// this->m_pod = uf::pointeredUserdata::copy( userdata.m_pod );
|
this->create( userdata.m_pod.len, userdata.m_pod.data, userdata.m_pod.type );
|
||||||
this->create( userdata.m_pod.len, userdata.m_pod.data );
|
|
||||||
// this->m_pod.type = userdata.m_pod.type;
|
|
||||||
/*
|
|
||||||
// if ( this->m_pod && copy.m_pod ) uf::pointeredUserdata::copy( *this->m_pod, *copy.m_pod );
|
|
||||||
if ( !userdata ) return;
|
|
||||||
this->destroy();
|
|
||||||
// this->m_pod = uf::pointeredUserdata::copy( userdata.m_pod );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// D-tor
|
// D-tor
|
||||||
uf::PointeredUserdata::~PointeredUserdata() noexcept {
|
uf::PointeredUserdata::~PointeredUserdata() noexcept {
|
||||||
@ -136,6 +137,7 @@ uf::PointeredUserdata::~PointeredUserdata() noexcept {
|
|||||||
// Destroys the POD
|
// Destroys the POD
|
||||||
void uf::PointeredUserdata::destroy() {
|
void uf::PointeredUserdata::destroy() {
|
||||||
uf::pointeredUserdata::destroy( this->m_pod );
|
uf::pointeredUserdata::destroy( this->m_pod );
|
||||||
|
this->m_pod = {};
|
||||||
}
|
}
|
||||||
// POD access
|
// POD access
|
||||||
// Returns a reference of POD
|
// Returns a reference of POD
|
||||||
@ -166,14 +168,18 @@ uf::PointeredUserdata::operator bool() const {
|
|||||||
return this->initialized();
|
return this->initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
uf::PointeredUserdata& uf::PointeredUserdata::operator=( pod::PointeredUserdata pointer ) {
|
uf::PointeredUserdata& uf::PointeredUserdata::operator=( const pod::PointeredUserdata& userdata ) {
|
||||||
this->m_pod = pointer;
|
this->create( userdata.len, userdata.data, userdata.type );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
uf::PointeredUserdata& uf::PointeredUserdata::operator=( PointeredUserdata&& move ) {
|
uf::PointeredUserdata& uf::PointeredUserdata::operator=( PointeredUserdata&& move ) {
|
||||||
if ( this->initialized() && move.initialized() ) {
|
if ( this->m_pod.data != move.m_pod.data ) {
|
||||||
|
this->destroy();
|
||||||
this->m_pod = move.m_pod;
|
this->m_pod = move.m_pod;
|
||||||
|
this->autoDestruct = move.autoDestruct;
|
||||||
|
|
||||||
move.m_pod = {};
|
move.m_pod = {};
|
||||||
|
move.autoDestruct = false;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
uf::MemoryPool uf::userdata::memoryPool;
|
uf::MemoryPool uf::userdata::memoryPool;
|
||||||
bool uf::userdata::autoDestruct = true;
|
bool uf::userdata::autoDestruct = true;
|
||||||
bool uf::userdata::autoValidate = true;
|
bool uf::userdata::autoValidate = true;
|
||||||
|
|
||||||
|
uf::stl::unordered_map<UF_USERDATA_CTTI_TYPE, pod::UserdataTraits> uf::userdata::traits;
|
||||||
|
|
||||||
// Constructs a pod::Userdata struct
|
// Constructs a pod::Userdata struct
|
||||||
pod::Userdata* uf::userdata::create( std::size_t len, void* data ) {
|
pod::Userdata* uf::userdata::create( std::size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
return uf::userdata::create( uf::userdata::memoryPool, len, data );
|
return uf::userdata::create( uf::userdata::memoryPool, len, data, type );
|
||||||
}
|
}
|
||||||
void uf::userdata::destroy( pod::Userdata* userdata ) {
|
void uf::userdata::destroy( pod::Userdata* userdata ) {
|
||||||
return uf::userdata::destroy( uf::userdata::memoryPool, userdata );
|
return uf::userdata::destroy( uf::userdata::memoryPool, userdata );
|
||||||
@ -23,7 +26,7 @@ size_t uf::userdata::size( size_t len, size_t padding ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, size_t len, void* data ) {
|
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
if ( len <= 0 ) return NULL;
|
if ( len <= 0 ) return NULL;
|
||||||
size_t requestedLen = size( len );
|
size_t requestedLen = size( len );
|
||||||
#if UF_MEMORYPOOL_INVALID_MALLOC
|
#if UF_MEMORYPOOL_INVALID_MALLOC
|
||||||
@ -40,13 +43,19 @@ pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, size_t
|
|||||||
userdata = (pod::Userdata*) uf::allocator::malloc_m( requestedLen ); // allocate data for the userdata struct, and then some
|
userdata = (pod::Userdata*) uf::allocator::malloc_m( requestedLen ); // allocate data for the userdata struct, and then some
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ( data ) memcpy( userdata->data, data, len );
|
userdata->len = requestedLen;
|
||||||
else memset( userdata->data, 0, len );
|
userdata->type = type;
|
||||||
userdata->len = len;
|
auto& trait = uf::userdata::getTrait( userdata->type );
|
||||||
userdata->type = UF_USERDATA_CTTI(void);
|
if ( data && userdata->type != UF_USERDATA_CTTI(void) ) trait.constructor( userdata->data, data );
|
||||||
|
else if ( data ) memcpy( userdata->data, data, requestedLen );
|
||||||
|
else memset( userdata->data, 0, requestedLen );
|
||||||
|
//UF_MSG_DEBUG("Calling create: {}: {}", trait.name, (void*) userdata->data);
|
||||||
return userdata;
|
return userdata;
|
||||||
}
|
}
|
||||||
void uf::userdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::Userdata* userdata ) {
|
void uf::userdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::Userdata* userdata ) {
|
||||||
|
auto& trait = uf::userdata::getTrait( userdata->type );
|
||||||
|
if ( userdata->type != UF_USERDATA_CTTI(void) ) trait.destructor( userdata->data );
|
||||||
|
//UF_MSG_DEBUG("Calling destroy: {}: {}", trait.name, (void*) userdata->data);
|
||||||
#if UF_MEMORYPOOL_INVALID_FREE
|
#if UF_MEMORYPOOL_INVALID_FREE
|
||||||
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::memoryPool::global;
|
||||||
memoryPool.free( userdata, size(userdata->len) );
|
memoryPool.free( userdata, size(userdata->len) );
|
||||||
@ -61,11 +70,14 @@ void uf::userdata::destroy( uf::MemoryPool& requestedMemoryPool, pod::Userdata*
|
|||||||
}
|
}
|
||||||
pod::Userdata* uf::userdata::copy( uf::MemoryPool& requestedMemoryPool, const pod::Userdata* userdata ) {
|
pod::Userdata* uf::userdata::copy( uf::MemoryPool& requestedMemoryPool, const pod::Userdata* userdata ) {
|
||||||
if ( !userdata || userdata->len <= 0 ) return NULL;
|
if ( !userdata || userdata->len <= 0 ) return NULL;
|
||||||
auto* copied = uf::userdata::create( userdata->len, const_cast<void*>((const void*) &userdata->data[0]) );
|
auto* copied = uf::userdata::create( userdata->len, const_cast<void*>((const void*) &userdata->data[0]), userdata->type );
|
||||||
copied->type = userdata->type;
|
|
||||||
return copied;
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pod::UserdataTraits& uf::userdata::getTrait( UF_USERDATA_CTTI_TYPE type ) {
|
||||||
|
return uf::userdata::traits[type];
|
||||||
|
}
|
||||||
|
|
||||||
uf::stl::string uf::userdata::toBase64( pod::Userdata* userdata ) {
|
uf::stl::string uf::userdata::toBase64( pod::Userdata* userdata ) {
|
||||||
return uf::base64::encode( userdata->data, userdata->len );
|
return uf::base64::encode( userdata->data, userdata->len );
|
||||||
}
|
}
|
||||||
@ -76,8 +88,8 @@ pod::Userdata* uf::userdata::fromBase64( const uf::stl::string& base64 ) {
|
|||||||
// C-tor
|
// C-tor
|
||||||
|
|
||||||
// Initializes POD
|
// Initializes POD
|
||||||
uf::Userdata::Userdata(std::size_t len, void* data) : m_pod(NULL), autoDestruct(uf::userdata::autoDestruct) {
|
uf::Userdata::Userdata(std::size_t len, const void* data, UF_USERDATA_CTTI_TYPE type) : m_pod(NULL), autoDestruct(uf::userdata::autoDestruct) {
|
||||||
if ( len && data ) this->create(len, data);
|
if ( len && data ) this->create(len, data, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes from POD
|
// Initializes from POD
|
||||||
@ -87,8 +99,9 @@ uf::Userdata::Userdata( pod::Userdata* pointer ) : m_pod(pointer), autoDestruct(
|
|||||||
|
|
||||||
// Move c-tor
|
// Move c-tor
|
||||||
uf::Userdata::Userdata( Userdata&& move ) noexcept :
|
uf::Userdata::Userdata( Userdata&& move ) noexcept :
|
||||||
m_pod(std::move(move.m_pod)),
|
m_pod(move.m_pod),
|
||||||
autoDestruct(move.autoDestruct) {
|
autoDestruct(move.autoDestruct) {
|
||||||
|
move.m_pod = {};
|
||||||
}
|
}
|
||||||
// Copy c-tor
|
// Copy c-tor
|
||||||
uf::Userdata::Userdata( const Userdata& userdata ) {
|
uf::Userdata::Userdata( const Userdata& userdata ) {
|
||||||
@ -97,10 +110,10 @@ uf::Userdata::Userdata( const Userdata& userdata ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates the POD
|
// Creates the POD
|
||||||
pod::Userdata* uf::Userdata::create( std::size_t len, void* data ) {
|
pod::Userdata* uf::Userdata::create( std::size_t len, const void* data, UF_USERDATA_CTTI_TYPE type ) {
|
||||||
if ( len <= 0 ) return NULL;
|
if ( len <= 0 ) return NULL;
|
||||||
this->destroy();
|
this->destroy();
|
||||||
return this->m_pod = uf::userdata::create( len, data );
|
return this->m_pod = uf::userdata::create( len, data, type );
|
||||||
}
|
}
|
||||||
void uf::Userdata::move( Userdata& moved ) {
|
void uf::Userdata::move( Userdata& moved ) {
|
||||||
// if ( this->m_pod && move.m_pod ) uf::userdata::move( *this->m_pod, *move.m_pod );
|
// if ( this->m_pod && move.m_pod ) uf::userdata::move( *this->m_pod, *move.m_pod );
|
||||||
@ -117,15 +130,7 @@ void uf::Userdata::move( Userdata&& moved ) {
|
|||||||
void uf::Userdata::copy( const Userdata& userdata ) {
|
void uf::Userdata::copy( const Userdata& userdata ) {
|
||||||
if ( !userdata.m_pod || !userdata.m_pod->len ) return;
|
if ( !userdata.m_pod || !userdata.m_pod->len ) return;
|
||||||
this->destroy();
|
this->destroy();
|
||||||
// this->m_pod = uf::userdata::copy( userdata.m_pod );
|
this->create( userdata.m_pod->len, userdata.m_pod->data, userdata.m_pod->type );
|
||||||
this->create( userdata.m_pod->len, userdata.m_pod->data );
|
|
||||||
// this->m_pod->type = userdata.m_pod->type;
|
|
||||||
/*
|
|
||||||
// if ( this->m_pod && copy.m_pod ) uf::userdata::copy( *this->m_pod, *copy.m_pod );
|
|
||||||
if ( !userdata ) return;
|
|
||||||
this->destroy();
|
|
||||||
// this->m_pod = uf::userdata::copy( userdata.m_pod );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// D-tor
|
// D-tor
|
||||||
uf::Userdata::~Userdata() noexcept {
|
uf::Userdata::~Userdata() noexcept {
|
||||||
@ -173,7 +178,10 @@ uf::Userdata& uf::Userdata::operator=( pod::Userdata* pointer ) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
uf::Userdata& uf::Userdata::operator=( Userdata&& move ) {
|
uf::Userdata& uf::Userdata::operator=( Userdata&& move ) {
|
||||||
if ( this->m_pod && move.m_pod ) this->m_pod = move.m_pod, move.m_pod = NULL;
|
if ( this->m_pod && move.m_pod ) {
|
||||||
|
this->m_pod = move.m_pod;
|
||||||
|
move.m_pod = NULL;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
uf::Userdata& uf::Userdata::operator=( const Userdata& copy ) {
|
uf::Userdata& uf::Userdata::operator=( const Userdata& copy ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user