📄 auto_destructor.hpp
字号:
public:
/// Detaches the managed instance from the auto_array_destructor and returns a pointer to it to the caller
///
/// \note The caller becomes responsible for destroying the instance.
value_type *detach()
{
value_type *t = m_value;
m_value = 0;
return t;
}
/// @}
/// \name Accessors
/// @{
public:
/// Implicit conversion to pointer to the managed instance
value_type* operator ->()
{
return m_value;
}
/// Implicit conversion to pointer-to-const to the managed instance
value_type const* operator ->() const
{
return m_value;
}
/// Returns the pointer
value_type* get_ptr()
{
return m_value;
}
/// Returns the pointer
value_type const* get_ptr() const
{
return m_value;
}
/// Returns the pointer
value_type* get()
{
return m_value;
}
/// Returns the pointer
value_type const* get() const
{
return m_value;
}
/// @}
/// \name Members
/// @{
private:
value_type* m_value;
/// @}
// Not to be implemented
private:
auto_array_destructor(class_type const& rhs);
auto_array_destructor const& operator =(class_type const& rhs);
};
// class return_value_destructor
/** \brief This class acts as a return-value scope variable that manages
* heap-allocated object instances.
*
* \ingroup group__library__memory
*
* \param T The value type
*
* \see stlsoft::auto_destructor
*/
template <ss_typename_param_k T>
class return_value_destructor
{
/// \name Types
/// @{
public:
/// The value type
typedef T value_type;
/// The current parameterisation of the type
typedef return_value_destructor<T> class_type;
/// The auto type
typedef auto_destructor<T> auto_type;
private:
/// The proxy type
typedef move_proxy<T, class_type> proxy_type;
/// @}
/// \name Construction
/// @{
public:
#ifdef STLSOFT_RETURN_VALUE_DESTRUCTOR_ENABLE_DIRECT_CTOR
/// Constructs from the pointer to an instance whose lifetime will be managedd
return_value_destructor(value_type *pt)
: m_value(pt)
{}
#endif /* STLSOFT_RETURN_VALUE_DESTRUCTOR_ENABLE_DIRECT_CTOR */
/// Construct from an auto_destructor<T>, transferring the managed instance from it
return_value_destructor(auto_type& rhs) // Note: not explicit
: m_value(rhs.detach())
{}
/// Move constructor
return_value_destructor(class_type& rhs)
: m_value(rhs.detach())
{}
/// Proxy move constructor
return_value_destructor(proxy_type rhs)
: m_value(rhs.m_value)
{}
/// Destroys the managed instance
~return_value_destructor() stlsoft_throw_0()
{
// This fires a report if value is non-zero, which indicates that
// the return value had not been used. This is arguably ok since this
// only ever happens in debug builds (what would be the point in
// including in a release build?), so its violation of the rules on
// no-throw destructors can be forgiven.
#ifndef STLSOFT_RETURN_VALUE_DESTRUCTOR_DISABLE_UNUSED_ASSERT
# if defined(STLSOFT_COMPILER_IS_WATCOM)
STLSOFT_ASSERT(m_value == 0);
# else /* ? compiler */
STLSOFT_MESSAGE_ASSERT("This return value was not used", m_value == 0);
# endif /* compiler */
#endif /* !STLSOFT_RETURN_VALUE_DESTRUCTOR_DISABLE_UNUSED_ASSERT */
delete m_value;
}
/// Proxy conversion operator
operator proxy_type()
{
return proxy_type(detach());
}
/// @}
/// \name Operations
/// @{
private:
friend class auto_destructor<T>;
/// Detaches the managed instance from the return_value_destructor and returns a pointer to it to the caller
///
/// \note The caller becomes responsible for destroying the instance.
value_type *detach()
{
value_type *t = m_value;
m_value = 0;
return t;
}
/// @}
/// \name Members
/// @{
private:
value_type *m_value;
/// @}
// Not to be implemented
private:
return_value_destructor const& operator =(class_type const& rhs);
};
// class return_value_array_destructor
/** \brief This class acts as a return-value scope variable that manages
* heap-allocated object arrays.
*
* \ingroup group__library__memory
*
* \param T The value type
*
* \see stlsoft::auto_array_destructor
*/
template <ss_typename_param_k T>
class return_value_array_destructor
{
/// \name Types
/// @{
public:
/// The value type
typedef T value_type;
/// The current parameterisation of the type
typedef return_value_array_destructor<T> class_type;
/// The auto type
typedef auto_array_destructor<T> auto_type;
private:
/// The proxy type
typedef move_proxy<T, class_type> proxy_type;
/// @}
/// \name Construction
/// @{
public:
#ifdef STLSOFT_RETURN_VALUE_DESTRUCTOR_ENABLE_DIRECT_CTOR
/// Constructs from the pointer to the array whose lifetimes will be managedd
ss_explicit_k return_value_array_destructor(value_type t[])
: m_value(t)
{}
#endif /* STLSOFT_RETURN_VALUE_DESTRUCTOR_ENABLE_DIRECT_CTOR */
/// Constructs from an auto_array_destructor<T> instance, transferring the managed array from it
return_value_array_destructor(auto_type& rhs) // Note: not explicit
: m_value(rhs.detach())
{}
#if 1
/// Move constructor
return_value_array_destructor(class_type& rhs)
: m_value(rhs.detach())
{}
#endif /* 0 */
/// Proxy move constructor
return_value_array_destructor(proxy_type rhs)
: m_value(rhs.m_value)
{}
/// Destroys the managed array
~return_value_array_destructor() stlsoft_throw_0()
{
// This fires a report if value is non-zero, which indicates that
// the return value had not been used. This is arguably ok since this
// only ever happens in debug builds (what would be the point in
// including in a release build?), so its violation of the rules on
// no-throw destructors can be forgiven.
#ifndef _STLSOFT_RETURN_VALUE_DESTRUCTOR_DISABLE_UNUSED_ASSERT
# if defined(STLSOFT_COMPILER_IS_WATCOM)
STLSOFT_ASSERT(m_value == 0);
# else /* ? compiler */
STLSOFT_MESSAGE_ASSERT("This return value was not used", m_value == 0);
# endif /* compiler */
#endif /* !_STLSOFT_RETURN_VALUE_DESTRUCTOR_DISABLE_UNUSED_ASSERT */
delete [] m_value;
}
/// Proxy conversion operator
operator proxy_type()
{
return proxy_type(detach());
}
/// @}
/// \name Operations
/// @{
private:
friend class auto_array_destructor<T>;
/// Detaches the managed instance from the return_value_array_destructor and returns a pointer to it to the caller
///
/// \note The caller becomes responsible for destroying the instance.
value_type *detach()
{
value_type *t = m_value;
m_value = 0;
return t;
}
/// @}
/// \name Members
/// @{
private:
value_type *m_value;
/// @}
// Not to be implemented
private:
return_value_array_destructor const& operator =(class_type const& rhs);
};
/* /////////////////////////////////////////////////////////////////////////
* Shims
*/
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T *get_ptr(auto_destructor<T> &ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T const* get_ptr(auto_destructor<T> const& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T* get_ptr(return_value_destructor<T>& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T const* get_ptr(return_value_destructor<T> const& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T* get_ptr(auto_array_destructor<T>& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T const* get_ptr(auto_array_destructor<T> const& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T* get_ptr(return_value_array_destructor<T>& ad)
{
return ad.get_ptr();
}
/** \brief
* \ingroup group__concept__shim__pointer_attribute__get_ptr
*/
template <ss_typename_param_k T>
inline T const* get_ptr(return_value_array_destructor<T> const& ad)
{
return ad.get_ptr();
}
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _STLSOFT_NO_NAMESPACE
} // namespace stlsoft
#endif /* _STLSOFT_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Warnings
*/
#if defined(STLSOFT_COMPILER_IS_MSVC) && \
_MSC_VER < 1300
# pragma warning(default: 4284)
#endif /* compiler */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_DESTRUCTOR */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -