Garciat
3/18/2014 - 12:56 AM

count_digits.d

import std.stdio, std.typetuple, std.traits;

template maxexp(T, uint base, T acc = T.max, uint i = 0)
	if (isIntegral!T && base > 1)
{
	static if (acc == 0)
	{
		enum maxexp = i - 1;
	}
	else
	{
		enum maxexp = maxexp!(T, base, acc / base, i + 1);
	}
}

template explist(T, uint base)
	if (isIntegral!T && base > 1)
{
	template impl(T exp, Acc...)
	{
		static if (exp == 0)
		{
			alias impl = Acc;
		}
		else
		{
			alias impl = impl!(exp-1, Acc, cast(T)Acc[$-1]*base);
		}
	}
	
	alias explist = impl!(maxexp!(T, base), 1);
}

uint count_digits(uint base, T)(T val)
	if (isIntegral!T && base > 1)
{
	if (val == 0) return 0;
	return static_lowerbound!(explist!(T, base))(val) + 1;
}

template static_lowerbound(Values...)
{
	uint static_lowerbound(T)(T val)
	{
		uint impl(uint a, uint b)()
		{
			static if (b - a == 1)
			{
				return a;
			}
			else
			{
				enum mid = (a + b) / 2;

				if (val < Values[mid])
				{
					return impl!(a, mid)();
				}
				else
				{
					return impl!(mid, b)();
				}
			}
		}
		
		return impl!(0, Values.length)();
	}
}

int a;

int main()
{
	return count_digits!10(a);
}