/*** *auto_handle.h * * Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: automatic resource management, like std::auto_ptr for ref classes * * [Public] * ****/ #pragma once #if !defined (_INC_MSCLR_AUTO_HANDLE) #ifndef __cplusplus_cli #error ERROR: msclr libraries are not compatible with /clr:oldSyntax #endif /* __cplusplus_cli */ #include namespace msclr { // wrap a resource to enforce strict ownership and ensure proper cleanup template ref class auto_handle { private: // disallow explicit comparisons to _safe_bool bool operator==( _detail_class::_safe_bool ); bool operator!=( _detail_class::_safe_bool ); public: // Constructors auto_handle() : m_handle( nullptr ) { } // construct from object pointer auto_handle( _element_type ^ _ptr ) : m_handle( _ptr ) { } // construct by assuming pointer from _right auto_handle auto_handle(auto_handle<_element_type> % _right ) : m_handle( _right.release() ) { } template auto_handle( auto_handle<_other_type> % _right ) : m_handle( _right.release() ) { } // assign compatible _right auto_handle<_element_type> % operator=( auto_handle<_element_type> % _right ) { reset( _right.release() ); return *this; } template auto_handle<_element_type> % operator=( auto_handle<_other_type> % _right ) { reset( _right.release() ); return *this; } _element_type ^ get() { return m_handle; } // return pointer to class object (assume pointer) _element_type ^ operator->() { return m_handle; } // for use when auto_handle appears in a conditional operator _detail_class::_safe_bool() { return valid() ? _detail_class::_safe_true : _detail_class::_safe_false; } // for use when auto_handle appears in a conditional bool operator!() { return ! valid(); } template operator auto_handle<_other_type>() { return auto_handle<_other_type>( *this ); } void swap( auto_handle<_element_type> % _right ) { auto_handle<_element_type> tmp = _right; _right = *this; *this = tmp; } void reset( _element_type ^ _new_ptr ) { if( m_handle != _new_ptr ) { if( valid() ) { delete m_handle; } m_handle = _new_ptr; } } void reset( ) { reset(nullptr); } _element_type ^ release() { _element_type ^_tmp_ptr = m_handle; m_handle = nullptr; return _tmp_ptr; } // destroy the object ~auto_handle() { if( valid() ) { delete m_handle; } } private: bool valid() { // see if the managed resource is in the invalid state. return m_handle != nullptr; } // the wrapped object _element_type ^ m_handle; }; // swap the contents of two auto_handle objects template void swap( auto_handle<_element_type> % _left, auto_handle<_element_type> % _right ) { _left.swap( _right ); } } // namespace msclr #define _INC_MSCLR_AUTO_HANDLE #endif /* !defined (_INC_MSCLR_AUTO_HANDLE) */