The Software Purist |

TAG | Architecture

Nov/09

24

Ada-like Range Validations

Here’s another post that I have migrated from my old blog. I will post up a follow-up in the future.

I’ve been reading a pretty cool blog and I wanted to post some of the feedback I had for his ideas here. Mr. Edd’s blog is at: http://www.mr-edd.co.uk/?p=99#comment-4313

Basically here’s what I wrote to Mr. Edd. I’ll fill in some more background later, perhaps:

Interesting post and I did want to compliment you on having an awesome blog. I totally see where you’re going with this, although when I did something to this effect, I implemented things with a slightly different approach. The one concern was too many implementation details slipping into the interface in cases where that information might be confusing or not helpful. What I had developed some years back, was template wrappers around primitives, as well. Upon any operation in the primitive wrapper where a value might be changed, I did a check to check it’s validity, based on template arguments to the class which specified a valid range. Then, in a class like matrix, the member would be of this safer type. Here’s a quick (certainly not optimized) example for a dynamic matrix:

template <class T, class TRangePolicy>
class RangedPrimitive
{
public:
	… provide overloads for every operation that can be done
	… on a primitive upon each overload, if there is a possibility
	… of being outside the range, check and throw an
	… exception if so …

	// one example to demonstrate
	RangedPrimitive& operator=(const T& value)
	{
		if (!TRangePolicy::isValid(value))
		{
			throw Constraint_Error();
		}
		internalValue_ = value.internalValue_;
		return *this;
	}
};

template <class T>
class Matrix
{
public:

	void set(size_t row, size_t column, const T& value)
	{
		// This line would throw based if the range policy of the element was violated
		elements_.at(row, column) = value;
	}

private:
	std::vector<std::vector<RangedPrimitive<T, RangeDisallowNans> > > elements_;
};

I got this idea because at my first job, I did a lot of Ada, and Ada had the idea of valid ranges and subranges built into the language. It definitely made things a lot easier, because there was a defined exception called Constraint_Error that occurred whenever an attempt was made to set something outside the range. Ada compilers also had the ability to check for any range violations they could figure out statically. So, for example, if you did something like the following:

rangedValue = 0.0 / 0.0;

you would actually get a compile error. You can simulate this in C++ by providing template versions of all methods that take a value rather than a type and remembering to call those, but I think that gets a bit messy.

At the time, Edd also posted this comment:

July 13, 2008 1:05 PM

Hey! I’m glad you’re enjoying my little corner of the internet!

The RangedPrimitive idea is nice and I can think of a number of applications.

As it happens, I came across the same technique on DDJ only a few days ago. You might be interested in the alternative implementation given there

· · · ·

Theme Design by devolux.nh2.me