Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*
 *  smart_ptr.h
 *  elftosb
 *
 *  Created by Chris Reed on 4/18/06.
 *  Copyright 2006 __MyCompanyName__. All rights reserved.
 *
 */
#if !defined(_smart_ptr_h_)
#define _smart_ptr_h_

/*!
 * \brief Simple, standard smart pointer class.
 *
 * This class only supports the single-owner paradigm.
 */
template <typename T>
class smart_ptr
{
public:
	typedef T data_type;
	typedef T * ptr_type;
	typedef const T * const_ptr_type;
	typedef T & ref_type;
	typedef const T & const_ref_type;
	
	//! Default constuctor. Initialises with no pointer set.
	smart_ptr() : _p(0) {}
	
	//! This constructor takes a pointer to the object to be deleted.
	smart_ptr(ptr_type p) : _p(p) {}
	
	//! Destructor. If an object (pointer) has been set, it will be deleted.
	//! Deletes the object using safe_delete().
	virtual ~smart_ptr() { safe_delete(); }
	
	//! Return the current pointer value.
	ptr_type get() { return _p; }
	
	//! Return the const form of the current pointer value.
	const_ptr_type get() const { return _p; }
	
	//! Change the pointer value, or set if if the default constructor was used.
	//! If a pointer had previously been associated with the object, and \a p is
	//! different than that previous pointer, it will be deleted before taking
	//! ownership of \a p. If this is not desired, call reset() beforehand.
	void set(ptr_type p)
	{
		if (_p && p != _p)
		{
			safe_delete();
		}
		_p = p;
	}
	
	//! Dissociates any previously set pointer value without deleting it.
	void reset() { _p = 0; }
	
	//! Dissociates a previously set pointer value, deleting it at the same time.
	void clear() { safe_delete(); }
	
	//! Forces immediate deletion of the object. If you are planning on using
	//! this method, think about just using a normal pointer. It probably makes
	//! more sense.
	virtual void safe_delete()
	{
		if (_p)
		{
			delete _p;
			_p = 0;
		} 
	}
	
	//! \name Operators
	//@{
	
	//! Makes the object transparent as the template type.
	operator ptr_type () { return _p; }
	
	//! Const version of the pointer operator.
	operator const_ptr_type () const { return _p; }
	
	//! Makes the object transparent as a reference of the template type.
	operator ref_type () { return *_p; }
	
	//! Const version of the reference operator.
	operator const_ref_type () const { return *_p; }
	
	//! Returns a boolean indicating whether the object has a pointer set or not.
	operator bool () const { return _p != 0; }
	
	//! To allow setting the pointer directly. Equivalent to a call to set().
	smart_ptr<T> & operator = (const_ptr_type p)
	{
		set(const_cast<ptr_type>(p));
		return *this;
	}
	
	//! Another operator to allow you to treat the object just like a pointer.
	ptr_type operator ->() { return _p; }
	
	//! Another operator to allow you to treat the object just like a pointer.
	const_ptr_type operator ->() const { return _p; }
	
//	//! Pointer dereferencing operator.
//	ref_type operator * () const { return *_p; }
//	
//	//! Const version of the pointer dereference operator.
//	const_ref_type operator * () const { return *_p; }
	
	//@}

protected:
	ptr_type _p;	//!< The wrapped pointer.
};

/*!
 * \brief Simple, standard smart pointer class that uses the array delete operator.
 *
 * This class only supports the single-owner paradigm.
 *
 * This is almost entirely a copy of smart_ptr since the final C++ specification
 * does not allow template subclass members to access members  of the parent that
 * do not depend on the template parameter.
 */
template <typename T>
class smart_array_ptr
{
public:
	typedef T data_type;
	typedef T * ptr_type;
	typedef const T * const_ptr_type;
	typedef T & ref_type;
	typedef const T & const_ref_type;
	
	//! Default constuctor. Initialises with no pointer set.
	smart_array_ptr() : _p(0) {}
	
	//! This constructor takes a pointer to the object to be deleted.
	smart_array_ptr(ptr_type p) : _p(p) {}
	
	//! Destructor. If an array has been set, it will be deleted.
	//! Deletes the array using safe_delete().
	virtual ~smart_array_ptr() { safe_delete(); }
	
	//! Return the current pointer value.
	ptr_type get() { return _p; }
	
	//! Return the const form of the current pointer value.
	const_ptr_type get() const { return _p; }
	
	//! Change the pointer value, or set if if the default constructor was used.
	//! If a pointer had previously been associated with the object, and \a p is
	//! different than that previous pointer, it will be deleted before taking
	//! ownership of \a p. If this is not desired, call reset() beforehand.
	void set(ptr_type p)
	{
		if (_p && p != _p)
		{
			safe_delete();
		}
		_p = p;
	}
	
	//! Dissociates any previously set pointer value without deleting it.
	void reset() { _p = 0; }
	
	//! Dissociates a previously set pointer value, deleting it at the same time.
	void clear() { safe_delete(); }
	
	//! Forces immediate deletion of the object. If you are planning on using
	//! this method, think about just using a normal pointer. It probably makes
	//! more sense.
	virtual void safe_delete()
	{
		if (_p)
		{
			delete [] _p;
			_p = 0;
		} 
	}
	
	//! \name Operators
	//@{
	
	//! Makes the object transparent as the template type.
	operator ptr_type () { return _p; }
	
	//! Const version of the pointer operator.
	operator const_ptr_type () const { return _p; }
	
	//! Makes the object transparent as a reference of the template type.
	operator ref_type () { return *_p; }
	
	//! Const version of the reference operator.
	operator const_ref_type () const { return *_p; }
	
	//! Returns a boolean indicating whether the object has a pointer set or not.
	operator bool () const { return _p != 0; }
	
	//! To allow setting the pointer directly. Equivalent to a call to set().
	smart_array_ptr<T> & operator = (const_ptr_type p)
	{
		set(const_cast<ptr_type>(p));
		return *this;
	}
	
	//! Another operator to allow you to treat the object just like a pointer.
	ptr_type operator ->() { return _p; }
	
	//! Another operator to allow you to treat the object just like a pointer.
	const_ptr_type operator ->() const { return _p; }
	
	//! Indexing operator.
	ref_type operator [] (unsigned index) { return _p[index]; }
	
	//! Indexing operator.
	const_ref_type operator [] (unsigned index) const { return _p[index]; }
	
//	//! Pointer dereferencing operator.
//	ref_type operator * () const { return *_p; }
//	
//	//! Const version of the pointer dereference operator.
//	const_ref_type operator * () const { return *_p; }
	
	//@}

protected:
	ptr_type _p;	//!< The wrapped pointer.
};

#endif // _smart_ptr_h_