
#include <array>
#include <iostream>
#include <vector>

constexpr std::array<double, 5> p = { 1.0, 0.0, 3.0, 5.0, 0.0 };

template<size_t index, bool isZero>
struct DotProductCalculator
{
	static double Calculate(const std::vector<double>& xArg)
	{
		return (xArg[index] * p[index]) 
				+ DotProductCalculator<index - 1, p[index - 1] == 0.0>::Calculate(xArg);
	}
};

template<>
struct DotProductCalculator<0, true>
{
	static double Calculate(const std::vector<double>& xArg)
	{
		return 0.0;
	}
};

template<>
struct DotProductCalculator<0, false>
{
	static double Calculate(const std::vector<double>& xArg)
	{
		return xArg[0] * p[0];
	}
};

template<size_t index>
struct DotProductCalculator<index, true>
{
	static double Calculate(const std::vector<double>& xArg)
	{
		return 0.0 + DotProductCalculator<index - 1, p[index - 1] == 0.0>::Calculate(xArg);
	}
};

template<typename ArrayType>
double f_p_driver(const std::vector<double>& xArg, const ArrayType& pAsArgument) 
{
     return DotProductCalculator<std::tuple_size<ArrayType>::value - 1, 
     							p[std::tuple_size<ArrayType>::value -1] == 0.0>::Calculate(xArg); 
}

int main() 
{
	std::vector<double> x = { 1.0, 2.0, 3.0, 4.0, 5.0 };
	double result = f_p_driver(x, p);
	std::cout << "Result: " << result;
	return 0;
}