commit 192ef420c79a4a4097b5decce589e676bc1c44ca
parent 4778ae6d8e04f1dbfb40c559d75b4b34a085224a
Author: Morel BĂ©renger <berengermorel76@gmail.com>
Date: Fri, 14 Aug 2020 07:36:09 +0200
introduce my old unique_res<> template
I wrote this code years ago when I noticed that
std::unique_ptr<> takes, in practice, the size of 2
pointers when used to manage C structures, because the
destructor must, for a reason I don't understand, be setup
at construction time instead of statically at build time.
My implementation also allows to use RAII on non-pointer
resources, like file descriptors or OpenGL identifiers.
Diffstat:
2 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/btl/src/memory.hpp b/btl/src/memory.hpp
@@ -0,0 +1,122 @@
+#ifndef MEMORY_HPP
+#define MEMORY_HPP
+
+#include <utility>
+
+template <typename T>
+void generic_free( T* p )
+{
+ free( p );
+}
+
+template
+<
+ typename T,
+ T INVALID_VAL,
+ void(*DTOR)(T)
+>
+class weak_res
+{
+protected:
+ typedef weak_res<T,INVALID_VAL,DTOR> COMPLETE_TYPE;
+ T m_data;
+public:
+ bool valid( void ) const
+ {
+ return m_data != INVALID_VAL;
+ }
+
+ bool operator==( COMPLETE_TYPE const& other ) const
+ {
+ return m_data == other.m_data;
+ }
+
+ bool operator==( T const& other ) const
+ {
+ return m_data == other;
+ }
+
+ bool operator!=( COMPLETE_TYPE const& other ) const
+ {
+ return m_data != other.m_data;
+ }
+
+ bool operator!=( T const& other ) const
+ {
+ return m_data != other;
+ }
+
+ const T get( void ) const
+ {
+ return m_data;
+ }
+};
+
+template
+<
+ typename T,
+ T INVALID_VAL,
+ void(*DTOR)(T)
+>
+class unique_res : public weak_res<T,INVALID_VAL,DTOR>
+//class unique_res
+{
+ typedef unique_res<T,INVALID_VAL,DTOR> UNIQUE_TYPE;
+public:
+ unique_res( UNIQUE_TYPE const& ) = delete;
+ UNIQUE_TYPE& operator=( UNIQUE_TYPE const& other ) = delete;
+
+ unique_res( void )
+ {
+ this->m_data = INVALID_VAL;
+ }
+
+ unique_res( UNIQUE_TYPE && other )
+ {
+ this->m_data = other.m_data;
+ other.m_data = INVALID_VAL;
+ }
+
+ unique_res( T && src )
+ {
+ this->m_data = src;
+ src = INVALID_VAL;
+ }
+
+ UNIQUE_TYPE& operator=( UNIQUE_TYPE && other )
+ {
+ clear();
+ std::swap( this->m_data, other.m_data );
+ return *this;
+ }
+
+ UNIQUE_TYPE& operator=( T && other )
+ {
+ clear();
+ std::swap( this->m_data, other );
+ return *this;
+ }
+
+ T release( void )
+ {
+ T ret = this->m_data;
+ this->m_data = INVALID_VAL;
+ return ret;
+ }
+
+ void clear( void )
+ {
+ if( INVALID_VAL != this->m_data )
+ {
+ DTOR( this->m_data );
+ this->m_data = INVALID_VAL;
+ }
+ }
+
+ ~unique_res( void )
+ {
+ clear();
+ }
+};
+
+#endif
diff --git a/btl/src/string.cpp b/btl/src/string.cpp
@@ -1,5 +1,4 @@
#include <utility>
-#include <memory>
#include <string.h>
#include <stddef.h>
@@ -11,6 +10,7 @@
#include "vector.hpp"
#include "string.hpp"
+#include "memory.hpp"
string make_string( char const* str )
{
@@ -23,7 +23,7 @@ string make_string( wchar_t const* str )
{
string ret;
size_t str_sz = wcslen( str );
- std::unique_ptr<char> temp( static_cast<char*>( malloc( str_sz +1 ) ) );
+ unique_res<char*,nullptr,generic_free> temp( static_cast<char*>( malloc( str_sz +1 ) ) );
size_t sz = wcstombs( temp.get(), str, str_sz );
assert( sz == str_sz );
ret.assign( temp.get(), temp.get() + sz );