direct_ptr_iterator作った

C++で(*it)->hogeって書かなきゃいけないとき、いらいらするので書いてみた。

と思ったらboost::indirect_iteratorというものが既にあることに気づく。再発明すぎる。

struct Demo
{
	int a, b, c;
};

Demo demo = {1, 2, 3};
std::vector<Demo*> ptr_vector;

ptr_vector.push_back(&demo);

std::vector<Demo*>::iterator it;
std::cout << (*it)->a << ", " << (*it)->b << ", " << (*it)->c << std::endl;

こんなのを、

direct_ptr_iterator<std::vector<Demo*>::iterator> it(ptr_vector.begin());
std::cout << it->a << ", " << it->b << ", " << it->c << std::endl;

こう書けるようにするやつ。

実装はこんなの:
http://websvn.nyaxtstep.com/viewvc.cgi/sandpit/cplusplus/direct_ptr_iterator/direct_ptr_iterator.h?revision=803&view=markup

#ifndef _direct_ptr_iterator_h_
#define _direct_ptr_iterator_h_

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/call_traits.hpp>

template<typename ITER, typename PTR = typename ITER::value_type>
class direct_ptr_iterator
{
public:
	BOOST_STATIC_ASSERT(boost::is_pointer<PTR>::value);

	typedef PTR ptr_type;
	typedef typename boost::remove_pointer<PTR>::type raw_type;
	typedef typename boost::call_traits<raw_type>::reference ref_type;

	direct_ptr_iterator(const ITER& it)
	:	m_orig(it)
	{ /* NOP */ }

	ptr_type operator->() const
	{
		return *m_orig;	
	}

	ref_type operator*() const
	{
		return **m_orig;
	}

private:
	ITER m_orig;
};

#endif // _direct_ptr_iterator_h_

追記:id:h0shuさん作のpointerの方をwrapする別解:http://mainte.mine.nu/ptr_holder.cpp

私の方法だとiteratorの他メソッド(++とか)も全部定義しなおさなきゃいけないので、こちらの方が汎用性が高いです。