Reflections on isPalindrome

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Oct 24 15:06:40 PDT 2014


On Fri, Oct 24, 2014 at 09:56:18PM +0000, "Nordlöw" via Digitalmars-d-learn wrote:
> I would appreciate comments on my palindrome predicate function
> 
> bool isPalindrome(R)(in R range) @safe pure
>     if (isBidirectionalRange!(R))
> {
>     import std.range: retro, take;
>     import std.algorithm: equal;
>     static if (hasLength!R)
>     {
>         const mid = range.length/2; // too long for string
>         return equal(range.retro.take(mid),
>                      range.take(mid));
>     }
>     else
>     {
>         return range.retro.equal(range);
>     }
> }
[...]

I'd just do it the simple way using range primitives:

	bool isPalindrome(R)(in R range)
		if (isBidirectionalRange!R)
	{
		auto r = range.save;
		while (!r.empty)
		{
			if (r.front != r.back)
				return false;
			r.popFront();
			r.popBack();
		}
		return true;
	}

This is guaranteed to work on all bidirectional ranges in single-pass,
handles odd/even lengths correctly, and doesn't depend on .length.

Offhand remark: in general you shouldn't annotate template functions
with @safe or pure. Instead, let the compiler infer those attributes,
and use @safe/pure unittests with known @safe/pure ranges to ensure your
code itself doesn't introduce any un- at safe or impure operations.
Otherwise, your function cannot be used with a range that has un- at safe
or impure range methods.


T

-- 
Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.


More information about the Digitalmars-d-learn mailing list