...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

std::iterator_traits の練習

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

bool is_zero(int i)
{
	return (i == 0);
}

namespace basic
{
	// これだけ値を返す
	int find_if(int v[], int size, bool(*pred)(int))
	{
		for(int i=0; i<size; ++i)
		{
			if (pred(v[i]))
			{
				return v[i];
			}
		}
		return size;
	}
}

namespace pointer
{
	// 範囲と結果をポインタで扱うように変更
	int* find_if(int* first, int* last, bool(*pred)(int))
	{
		for(int* i=first; i!=last; ++i)
		{
			if (pred(*i))
			{
				return i;
			}
		}
		return last;
	}
}

namespace imcompleted_generic
{
	// ポインタを Iterator に変更
	template <typename Iterator>
	Iterator find_if(Iterator first, Iterator last, bool(*pred)(int)) // intをどうする?
	{
		for(Iterator i=first; i!=last; ++i)
		{
			if (pred(*i))
			{
				return i;
			}
		}
		return last;
	}
}

namespace generic
{
	// ポインタが T* のとき T を得るために iterator_traits を使うように変更
	template <typename Iterator>
	Iterator find_if(Iterator first, Iterator last, bool(*pred)(typename std::iterator_traits<Iterator>::value_type)) // iterator_traitsを使う
	{
		for(Iterator i=first; i!=last; ++i)
		{
			if (pred(*i))
			{
				return i;
			}
		}
		return last;
	}
}

// generic::find_if で使えるコンテナのサンプル
struct sample_container
{
	typedef int* iterator;
	typedef int value_type;

	int* v;
	int size;
	sample_container(int* array, int length)
	{
		size = length;
		v = new int[size];
		for(int i=0; i<size; ++i)
		{
			v[i] = array[i];
		}
	}
	~sample_container()
	{
		delete[] v;
	}
	iterator begin()
	{
		return &v[0];
	}
	iterator end()
	{
		return &v[size];
	}
};

int main()
{
	{
		using namespace basic;
		int array[] = {4,3,2,5,1,0};
		int value = find_if(array, 6, is_zero);
		std::cout << value << std::endl;
	}
	{
		using namespace pointer;
		int array[] = {4,3,2,5,1,0};
		int* iter = find_if(array, array+6, is_zero);
		if (array+6 != iter)
			std::cout << *iter << std::endl;
	}
	{
		using namespace generic;
		int array[] = {4,3,2,5,1,0};
		int* iter = find_if(array, array+6, is_zero);
		if (array+6 != iter)
			std::cout << *iter << std::endl;

		std::vector<int> v(array, array+6);
		std::vector<int>::iterator iter2 = find_if(v.begin(), v.end(), is_zero);
		if (v.end() != iter2)
			std::cout << *iter2 << std::endl;

		sample_container mc(array, 6);
		sample_container::iterator iter3 = find_if(mc.begin(), mc.end(), is_zero);
		if (mc.end() != iter3)
			std::cout << *iter3 << std::endl;
	}
	return 0;
}