tools

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

memory.hpp (3478B)


      1 // Copyright (c) 2020 Morel BĂ©renger
      2 // 
      3 // This software is provided 'as-is', without any express or implied
      4 // warranty. In no event will the authors be held liable for any damages
      5 // arising from the use of this software.
      6 // 
      7 // Permission is granted to anyone to use this software for any purpose,
      8 // including commercial applications, and to alter it and redistribute it
      9 // freely, subject to the following restrictions:
     10 // 
     11 // 1. The origin of this software must not be misrepresented; you must not
     12 //    claim that you wrote the original software. If you use this software
     13 //    in a product, an acknowledgment in the product documentation would be
     14 //    appreciated but is not required.
     15 // 2. Altered source versions must be plainly marked as such, and must not be
     16 //    misrepresented as being the original software.
     17 // 3. This notice may not be removed or altered from any source distribution.
     18 
     19 // This file defines unique_res and weak_res class utilities.
     20 // goal: easy RAII for any resource, without any assumption
     21 //   about what is an invalid value, and without consuming
     22 //   more data memory than a single, raw pointer.
     23 
     24 #ifndef MEMORY_HPP
     25 #define MEMORY_HPP
     26 
     27 #include <utility>
     28 
     29 // ease the life for memory stuff, just use:
     30 // typedef unique_res<T,nullptr,generic_free<T>> T_owner;
     31 // typedef weak_res<T,nullptr> T_owned;
     32 template <typename T>
     33 void generic_free( T* p )
     34 {
     35 	delete p;
     36 }
     37 
     38 // those classes are purely for semantics, and do not
     39 // provide any real guarantee, as anyone is free to call
     40 // `close()`, `free()` or whatever function able to release
     41 // resource in `T`, but at least it should make it easier to
     42 // understand that it is a bad idea.
     43 // Arrays are explicitly not handled, because that's what
     44 // vector is for. If you can't affort the small overhead of
     45 // one pointer per collection, you likely can afford to
     46 // write your own stuff.
     47 
     48 template
     49 <
     50 	typename T,
     51 	T INVALID_VAL
     52 >
     53 class weak_res
     54 {
     55 protected:
     56 	typedef weak_res<T,INVALID_VAL> COMPLETE_TYPE;
     57 	T m_data;
     58 public:
     59 	bool valid( void ) const
     60 	{
     61 		return m_data != INVALID_VAL;
     62 	}
     63 
     64 	bool operator==( COMPLETE_TYPE const& other ) const
     65 	{
     66 		return m_data == other.m_data;
     67 	}
     68 
     69 	bool operator==( T const& other ) const
     70 	{
     71 		return m_data == other;
     72 	}
     73 
     74 	bool operator!=( COMPLETE_TYPE const& other ) const
     75 	{
     76 		return m_data != other.m_data;
     77 	}
     78 
     79 	bool operator!=( T const& other ) const
     80 	{
     81 		return m_data != other;
     82 	}
     83 
     84 	const T get( void ) const
     85 	{
     86 		return m_data;
     87 	}
     88 };
     89 
     90 template
     91 <
     92 	typename T,
     93 	T INVALID_VAL,
     94 	void(*DTOR)(T)
     95 >
     96 class unique_res : public weak_res<T,INVALID_VAL>
     97 {
     98 	typedef unique_res<T,INVALID_VAL,DTOR> UNIQUE_TYPE;
     99 public:
    100 	unique_res( UNIQUE_TYPE const& ) = delete;
    101 	UNIQUE_TYPE& operator=( UNIQUE_TYPE const& other ) = delete;
    102 
    103 	unique_res( void )
    104 	{
    105 		this->m_data = INVALID_VAL;
    106 	}
    107 
    108 	unique_res( UNIQUE_TYPE && other )
    109 	{
    110 		this->m_data = other.m_data;
    111 		other.m_data = INVALID_VAL;
    112 	}
    113 
    114 	unique_res( T && src )
    115 	{
    116 		this->m_data = src;
    117 		src = INVALID_VAL;
    118 	}
    119 
    120 	UNIQUE_TYPE& operator=( UNIQUE_TYPE && other )
    121 	{
    122 		clear();
    123 		std::swap( this->m_data, other.m_data );
    124 		return *this;
    125 	}
    126 
    127 	UNIQUE_TYPE& operator=( T && other )
    128 	{
    129 		clear();
    130 		std::swap( this->m_data, other );
    131 		return *this;
    132 	}
    133 
    134 	T release( void )
    135 	{
    136 		T ret = this->m_data;
    137 		this->m_data = INVALID_VAL;
    138 		return ret;
    139 	}
    140 
    141 	void clear( void )
    142 	{
    143 		if( INVALID_VAL != this->m_data )
    144 		{
    145 			DTOR( this->m_data );
    146 			this->m_data = INVALID_VAL;
    147 		}
    148 	}
    149 
    150 	~unique_res( void )
    151 	{
    152 		clear();
    153 	}
    154 };
    155 
    156 #endif