To demonstrate the usage of Scrunitizer, we need a small example. Below you find the source code of a class for handling rectangles.

Some features of this rectangle class that need a bit of explanation:

  • The interface of the class is the x,y,width,height representation, because thatīs a bit more easy to handle. Note that a rectangle anchored at (0,0) with width 50 and height 100 has the opposite corner at location (49,99) and not (50,100)!. For this reason, and because quite often width and height are known, the two corner representation is not used in the interface (but see below).

  • The internal representation is (x0,y0),(x1,y1), so upper left and lower right corner coordinates. That representation is used because it is much more handy for implementing many of the member functions.

  • The implementation always checks if all involved rectangles have extend before they proceed. If not, an exception is thrown. A rectangle has extend when it is at least one unit wide and high. This prevents that meaningless (and eventually dangerous) results are produced when rectangles with no extend are involved.

To achieve higher code density and simplicity, all functions are defined inside the class definition. In a real implementation, some functions might be put in a separate source file.



class Rect {

	struct NoExtent { };

	private:
		int	_x0;
		int	_y0;
		int	_x1;
		int	_y1;

	public:
		Rect () : _x0 (0), _y0 (0), _x1 (-1), _y1 (-1) { }
		Rect (int x, int y, int width, int height) 
			: _x0 (x), _y0 (y), _x1 (x + width - 1), _y1 (y + height - 1) { }
		Rect (const Rect& src) : _x0 (src._x0), _y0 (src._y0), _x1 (src._x1), _y1 (src._y1) { }

		const Rect& operator= (const Rect& rhs) {
			_x0 = rhs._x0;
			_y0 = rhs._y0;
			_x1 = rhs._x1;
			_y1 = rhs._y1;
			return *this;
		}

	public:
		int x () const { return _x0; }
		int y () const { return _y0; }
		int width  () const { return _x1 - _x0 + 1; }
		int height () const { return _y1 - _y0 + 1; }

		bool hasExtent () const {
			return _x1 >= _x0 && _y1 >= _y0;
		}

		bool equals (const Rect& r) const {
			return	_x0 == r._x0 && _y0 == r._y0 &&
				_x1 == r._x1 && _y1 == r._y1;
		}

		bool intersects (const Rect& r) const {
			  checkExtent (); 
			r.checkExtent ();
			return	_x0 <= r._x1 && _x1 >= r._x0 &&
				_y0 <= r._y1 && _y1 >= r._y0 ;
		}

		void intersect (const Rect& r) {
			  checkExtent ();
			r.checkExtent ();
			_x0 = max (_x0, r._x0);
			_y0 = max (_y0, r._y0);
			_x1 = min (_x1, r._x1);
			_y1 = min (_y1, r._y1);
		}

		bool covers (const Rect& r) const {
			  checkExtent (); 
			r.checkExtent ();
			return	_x0 <= r._x0 && _x1 >= r._x1 &&
				_y0 <= r._y0 && _y1 >= r._y1 ;
		}

		void cover (const Rect& r) {
			  checkExtent ();
			r.checkExtent ();
			_x0 = min (_x0, r._x0);
			_y0 = min (_y0, r._y0);
			_x1 = max (_x1, r._x1);
			_y1 = max (_y1, r._y1);
		}

		bool contains (int x, int y) const {
			return _x0 <= x && x <= _x1 && _y0 <= y && y <= _y1;
		}

		void locate (int x, int y) {
			_x1 = x + _x1 - _x0;
			_y1 = y + _y1 - _y0;
			_x0 = x;
			_y0 = y;
		}

		void move (int dx, int dy) {
			_x0 += dx;
			_y0 += dy;
			_x1 += dx;
			_y1 += dy;
		}

		void resize (int w, int h) {
			_x1 = _x0 + w - 1;
			_y1 = _y0 + h - 1;
		}

		void reshape (int x, int y, int w, int h) {
			_x0 = x;
			_y0 = y;
			_x1 = x + w - 1;
			_y1 = y + h - 1;
		}

	protected:
		void checkExtent () const {
			if (! hasExtent ()) throw NoExtent ();
		}

	private:
		int max (int v1, int v2) const { return (v1 > v2) ? v1 : v2; }
		int min (int v1, int v2) const { return (v1 < v2) ? v1 : v2; }
};

The Scrunitizer C++ Unit Test Framework
by Bernd Linowski

[Scrunitizer]  [Overview]  [Cookbook]  [Download]  [Index]  [Linosphere]

Page generated: 1 Nov 2000
(C) by Bernd Linowski
scrunitizer@linosphere.de