tools

various tools
git clone git://deadbeef.fr/tools.git
Log | Files | Refs | README | LICENSE

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:
Abtl/src/memory.hpp | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbtl/src/string.cpp | 4++--
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 );