com_ptr

DirectXのCOM用のスマートポインタcom_ptr<>を書いてみた.

assertは書いてないけど.


合ってるのか不安だがw



#ifndef YUKIMI__UTILITY__COM_PTR_HPP
#define YUKIMI__UTILITY__COM_PTR_HPP

///
/// @file	/yukimi/utility/com_ptr.hpp
/// @brief	DirectXのCOM用のポインタ管理クラスの実装.
/// @author	GraighleFS
///


namespace {

#ifndef NULL
const int	NULL	= 0;
#endif

}


namespace ykm {


namespace utility {


///
/// @class	com_ptr.
/// @brief	DirectXのCOM用のポインタ管理クラス.
///			ObjectT	管理する型.
///

template<
	typename	ObjectT
>
struct com_ptr {

	typedef  ObjectT	value_type;

private:

	value_type*	pointee_;

public:

	///
	/// @brief		Constructor.
	/// @param[in]	管理するオブジェクトへのポインタ.
	/// @param[in]	com_ptrに管理を引渡した時に,参照カウントを増やすかどうか.
	/// @attention	add_ref_firstについては通常はfalseで構わない.
	///
	explicit com_ptr(value_type* ptr = NULL, bool add_ref_first = false):
	pointee_	(NULL){

		pointee_	= ptr;
		if(add_ref_first && pointee_)
			pointee_->AddRef();

	}


	///
	/// @brief		Copy-Constructor.
	///
	explicit com_ptr(const com_ptr<value_type>& org):
	pointee_	(org.pointee_){

		if(pointee_)
			pointee_->AddRef();

	}


	///
	/// @brief		Destructor.
	/// @throw		Nothrow.
	///
	~com_ptr() throw(){

		if(pointee_)
			pointee_->Release();

	}


	///
	/// @brief		Operator=().
	///
	com_ptr<value_type>& operator=(const com_ptr<value_type>& org){

		com_ptr<value_type> temp(org);
		swap(temp);
		return *this;

	}


	///
	/// @brief		Operator*().
	///
	value_type& operator*() const{

		//TODO: assert
		return *pointee_;

	}


	///
	/// @brief		Operator->().
	///
	value_type* operator->() const{

		//TODO: assert
		return pointee_;

	}


	///
	/// @brief		Operator&().
	///
	value_type** operator&() const{

		return &pointee_;

	}


	///
	/// @brief		Operator bool.
	/// @throw		Nothrow.
	///
	operator bool() const{

		return (pointee_ != NULL);

	}


	///
	/// @brief		Swap.
	/// @throw		Nothrow.
	///
	void swap(com_ptr<value_type>& other) throw(){

		value_type*	temp	= pointee_;
		pointee_			= other.pointee_;
		other.pointee_		= temp;

	}


	///
	/// @brief		管理するオブジェクトを再設定.
	/// @param[in]	管理を共有するcom_ptr.
	///
	void reset(const com_ptr<value_type>& other){

		com_ptr<value_type> temp(other.pointee_, true);
		swap(temp);

	}


	///
	/// @brief		管理するオブジェクトを再設定.
	/// @param[in]	管理するオブジェクトへのポインタ.
	/// @param[in]	com_ptrに管理を引渡した時に,参照カウントを増やすかどうか.
	/// @attention	add_ref_firstについては通常はfalseで構わない.
	///				別のcom_ptrと管理を共有する場合は,reset(const com_ptr<value_type>&);を使うこと.
	///
	void reset(value_type* ptr = NULL, bool add_ref_first = false){

		com_ptr<value_type> temp(ptr, add_ref_first);
		swap(temp);

	}


	///
	/// @brief		管理しているオブジェクトへのポインタを返す.
	/// @throw		Nothrow.
	///
	value_type* ptr() const{

		return pointee_;

	}


	///
	/// @brief		DirectXの生成メソッドに渡す時に便利なメソッド.
	///				管理しているオブジェクトを管理下からはずし,ポインタを返す.
	///
	value_type** released_ptr(){

		if(pointee_)
			pointee_->Release();
		pointee_ = NULL;
		return &pointee_;

	}


};


} // namespace utilitty


} // namespace ykm


#endif // YUKIMI__UTILITY__COM_PTR_HPP