intrusive_to_shared

近況報告もかねて、昨日10分で作った部品を紹介してみる。
boost::intrusive_ptr を boost::shared_ptr に変換するコードです。

#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>

struct intrusive_ptr_releaser
{
	typedef void result_type;
	
	template<typename T>
	void operator()( T* ptr ) const
	{
		intrusive_ptr_release(ptr);
	}

};	// class intrusive_ptr_releaser

template<typename T>
inline boost::shared_ptr<T> intrusive_to_shared( const boost::intrusive_ptr<T>& pt )
{
	T* p = pt.get();
	
	if(p)
	{
		intrusive_ptr_add_ref( p );
	}
	
	return boost::shared_ptr<T>( p, intrusive_ptr_releaser() );
}
template<typename T>
inline boost::shared_ptr<T> intrusive_to_shared( T* p, bool add_ref = true )
{
	if( p && add_ref )
	{
		intrusive_ptr_add_ref( p );
	}
	
	return boost::shared_ptr<T>( p, intrusive_ptr_releaser() );
}

気をつけたことは、例外安全になるように意識したことくらい(例外を投げる可能性があるのが intrusive_ptr_add_ref と shared_ptr のコンストラクタで、shared_ptr のコンストラクタは例外を投げる際に p を削除(今回は intrusive_ptr_release の呼び出しですが)してくれるので問題なし。add_ref で例外が投げられた場合には何もせず関数を抜けるので問題なし)。
こういうコード書いてると boost::shared_ptr って万能なんだなと改めて思います。
さて、冬コミの追い込みに戻ろうっと。