/* Check cf5-opt.vim defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:cppflags=g:Iboost.g:Itbb
VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
VIM: let g:ldlibpath=g:Bboost.g:Btbb
VIM: let g:argv=""
VIM-: let g:cf5output=0
*/
#include <iostream>
#include <exception>

template <int a>
struct A
{
	A()
	{
		std::cout << "A<" << a << ">" << std::endl;
	}
};

template <>
struct A<5>
{
	A()
	{
		std::cout << "special A<5>" << std::endl;
	}
};

template <class b, int a>
struct B
{
	B()
	{
		std::cout << "B<" << a << ">" << std::endl;
	}
};

template <class b>
struct B<b,5>
{
	B()
	{
		std::cout << "special B<5>" << std::endl;
	}
};

template <int a>
void f()
{
	std::cout << "f<" << a << ">()" << std::endl;
}

template <>
void f<5>()
{
	std::cout << "special f<5>()" << std::endl;
}

template <class b, int a>
void g()
{
	std::cout << "g<" << a << ">()" << std::endl;
}

/*
 * no partial specialisation for functions.
template <class b>
void g<b,5>()
{
	std::cout << "special g<5>()" << std::endl;
}
*/
template <>
void g<void,5>()
{
	std::cout << "special g<void,5>()" << std::endl;
}

int main ( void )
{try{

	A<1> a1;
	A<2> a2;
	A<5> a5;
	A<6> a6;
	
	B<void,1> b1;
	B<void,2> b2;
	B<void,5> b5;
	B<void,6> b6;

	f<1>();
	f<2>();
	f<5>();
	f<6>();

	g<void,1>();
	g<void,2>();
	g<void,5>();
	g<int,5>();
	g<void,6>();

	return 0;
}
catch ( const std::exception& e )
{
	std::cerr << std::endl
			<< "std::exception(\"" << e.what() << "\")." << std::endl;
	return 2;
}
catch ( ... )
{
	std::cerr  << std::endl
			<< "unknown exception." << std::endl;
	return 1;
}}

