head     1.23;
branch   ;
access   ;
symbols  ;
locks    ; strict;
comment  @// @;


1.23
date     92.07.01.13.55.08;  author thoth;  state Exp;
branches ;
next     1.22;

1.22
date     92.06.29.03.42.44;  author fischer;  state Exp;
branches ;
next     1.21;

1.21
date     92.06.28.05.19.30;  author fischer;  state Exp;
branches ;
next     1.20;

1.20
date     92.06.27.05.08.59;  author fischer;  state Exp;
branches ;
next     1.19;

1.19
date     92.06.21.17.04.23;  author thoth;  state Exp;
branches ;
next     1.18;

1.18
date     92.06.17.15.38.59;  author thoth;  state Exp;
branches ;
next     1.17;

1.17
date     92.06.17.15.22.51;  author thoth;  state Exp;
branches ;
next     1.16;

1.16
date     92.06.16.13.56.50;  author thoth;  state Exp;
branches ;
next     1.15;

1.15
date     92.06.10.11.55.32;  author thoth;  state Exp;
branches ;
next     1.14;

1.14
date     92.06.09.12.26.41;  author fischer;  state Exp;
branches ;
next     1.13;

1.13
date     92.06.08.02.48.25;  author fischer;  state Exp;
branches ;
next     1.12;

1.12
date     92.06.02.01.47.29;  author fischer;  state Exp;
branches ;
next     1.11;

1.11
date     92.05.27.07.45.07;  author fischer;  state Exp;
branches ;
next     1.10;

1.10
date     92.05.26.07.43.49;  author fischer;  state Exp;
branches ;
next     1.9;

1.9
date     92.05.22.07.13.39;  author fischer;  state Exp;
branches ;
next     1.8;

1.8
date     92.05.21.20.24.10;  author thoth;  state Exp;
branches ;
next     1.7;

1.7
date     92.05.21.15.09.52;  author thoth;  state Exp;
branches ;
next     1.6;

1.6
date     92.05.21.12.05.50;  author thoth;  state Exp;
branches ;
next     1.5;

1.5
date     92.05.21.08.06.47;  author fischer;  state Exp;
branches ;
next     1.4;

1.4
date     92.05.20.06.30.35;  author fischer;  state Exp;
branches ;
next     1.3;

1.3
date     92.05.18.15.15.00;  author thoth;  state Exp;
branches ;
next     1.2;

1.2
date     92.05.16.13.57.25;  author thoth;  state Exp;
branches ;
next     1.1;

1.1
date     92.05.16.13.46.19;  author thoth;  state Exp;
branches ;
next     ;


desc
@this is the implementation file for Coord, the image
algebra coordinate type.
@


1.23
log
@cleanup of integer stuff.
inlining of copy constructor and operator=
@
text
@// Emacs: -*- C++ -*-

static char rcsid[] = "$Id: Coord.cc,v 1.22 92/06/29 03:42:44 fischer Exp Locker: thoth $";

//
// $Log:	Coord.cc,v $
// Revision 1.22  92/06/29  03:42:44  fischer
// Added real Coord &operator= code, uncommented the ~Coord(). Just in case.
// 
// Revision 1.21  92/06/28  05:19:30  fischer
// Made promote accept const NumericType args, made it const member function.
// 
// Revision 1.20  92/06/27  05:08:59  fischer
// Added Coord(cont Coord&) constructor, since gcc wasn't making
// use of the default one it should have been.
// 
// Revision 1.19  92/06/21  17:04:23  thoth
// fixed heinous infinite recursion error introduced during
// throw robustification.  Operator int and float should now be repaired.
// 
// Revision 1.18  92/06/17  15:38:59  thoth
// fixed Coordinate input, duh
// 
// Revision 1.17  92/06/17  15:22:51  thoth
// added input and string conversion operations.
// 
// Revision 1.16  92/06/16  13:56:50  thoth
// updated to follow new enum constant conventions
// removed operations that only make sense on integers
// 
// Revision 1.15  92/06/10  11:55:32  thoth
// updated some more, to reflect new conventions.
// 
// Revision 1.14  92/06/09  12:26:41  fischer
// Made most Coord operators non-member friends to get 
// automatic type coercion.
// 
// Revision 1.13  92/06/08  02:48:25  fischer
// Simplified switch statements (removed Complex: and Rational:
// cases).  No extra break statements needed to be added (stylistic
// nit). Since Integer is the base type,  removed most calls to
// int(foo) $ int(bar)  where $ is some binary op,  replacing them
// with foo.value.i & bar.value.i.  This should result in substantial
// savings,  but will necessitate careful rewrite should a ``lower''
// type such as Char or Boolean be added to Coord.
// 
// Revision 1.12  92/06/02  01:47:29  fischer
// Made assignment operators const Coord&.  Removed 
// Removed !, &&, and ||.
// 
// Revision 1.11  92/05/27  07:45:07  fischer
// Added && and || as one arg friend functions, which is
// only way to preserve special semantics. Added bitwise
// compound assignment.  Changed bitwise operators to work
// between Coords, except for shift operators which now
// use signed ints.
// 
// Revision 1.11  1992/05/26  11:30:30  fischer
// Added more arithmetic and bitwise operators. Just a few to go.
//
// Revision 1.10  1992/05/24  11:44:53  fischer
// Added destructive assignment operations, pre- and post-
// increment and decrement.  Found << *will* work with gcc 2.0.
// None of this will work correctly with gcc 2.1 (overloading
// broken when application uses it).
//
// Revision 1.9  1992/05/22  07:13:39  fischer
// Got overloading to work by simple expedient of using math.ufl.edu
// version of g++:  gcc-2.0.
// Changed Coord arithmetic operators to assume result_type()
// is taking care of uninitialized Coord types (tag==None) via throw.
// Added default: to switches so Rob can rest easy about new
// NumericTypes.  Added *,/,+,%,-.  Lots more to go. Since we now
// have NumericType abstraction,  changed stuff like this->tag to
// this->type():  because these are inline functions, there should be little
// overhead, but we need to check with some timing tests.
// Changed Coord.val name to Coord.value name since I can never remember
// these damn c-style abbreviations.   .
//
// Revision 1.8  92/05/21  20:24:10  thoth
// switched to // comments for rcs log
// 
// Revision 1.7  92/05/21  15:09:52  thoth
// add addition operator.  Use of this operator
// causes the compiler to hang.
// declared some methods const (unmodifying).
// 
// Revision 1.6  92/05/21  12:05:50  thoth
// added handling for new NumericTypes.
// 
// Revision 1.5  92/05/21  08:06:47  fischer
// Started rework of CoordType to IA::NumericType
// so all classes can access.
// 
// Revision 1.4  92/05/20  06:30:35  fischer
// created a scheme to get around thoth's scheme:
// removed it.
// 
// Revision 1.3  92/05/18  15:15:00  thoth
// created a scheme to get around g++2.1's busted overloading
// and type conversion.
// 
// Revision 1.2  92/05/16  13:57:25  thoth
// added log goo
// 
// Revision 1.1  92/05/16  13:46:19  thoth
// Initial revision
//


// Warning:  If INTEGER is not the ``minimum'' type, everything in
// this file will need to be changed.

#include <ctype.h>
#include <stdlib.h>
#include "Coord.h"
#pragma implementation


int Coord::operator int() const
{
    switch (tag) {
    case INTEGER:
	return value.i;
    case NONE:
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
	return 0;
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

float Coord::operator float() const
{
    switch (this->tag) {
    case INTEGER:
	return this->value.i;
    case REAL:
	return this->value.f;
    case NONE:
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
	return 0;
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

// Rob: please note that result_type() never returns NONE.
// So I removed your throw(IA::TYPE_UNSPECIFIED).   If it 
// *did* return none, it would indicate a TYPE_MISMATCH, anyway.
// If one of the types passed to result_type() is NONE, result_type() 
// itself throws the TYPE_MISMATCH error.

Coord operator+ (const Coord& left, const Coord& right)
{
    switch(IA::result_type(left.type(), right.type())) {
    case INTEGER:
	return left.value.i + right.value.i;
    case REAL:
	return float(left) + float(right);
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

Coord operator* (const Coord &left,  const Coord &right)
{
    switch(IA::result_type(left.type(), right.type())) {
    case INTEGER:
	return left.value.i * right.value.i;
    case REAL:
	return float(left) * float(right);
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

Coord operator- (const Coord &left,  const Coord &right)
{
    switch(IA::result_type(left.type(), right.type())) {
    case INTEGER:
	return left.value.i - right.value.i;
    case REAL:
	return float(left) - float(right);
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

// N.B. Unary minus needs to check for uninitialized values (type==NONE) itself,
// since the function result_type() is not called as in most binary operations.
// result_type() throws IA::TYPE_UNSPECIFIED if it gets NONE, or finds no common
// type (latter case not yet possible).

Coord operator- (const Coord &right)
{
    switch(right.type()) {
    case INTEGER:
	return -right.value.i;
    case REAL:
	return -right.value.f;
    case NONE:
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
	return Coord();
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

Coord operator/ (const Coord &left,  const Coord &right)
{
    switch(IA::result_type(left.type(), right.type())) {
    case INTEGER:
	return left.value.i / right.value.i;
    case REAL:
	return float(left) / float(right);
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

const Coord& Coord::operator += (const Coord& rhs) 
{
    *this = *this + rhs;
    return  *this;
}

const Coord& Coord::operator -= (const Coord& rhs) 
{
    *this = *this - rhs;
    return  *this;
}

const Coord& Coord::operator *= (const Coord& rhs) 
{
    *this = *this * rhs;
    return  *this;
}

const Coord& Coord::operator /= (const Coord& rhs) 
{
    *this = *this / rhs;
    return  *this;
}

const Coord& Coord::operator %= (const Coord& rhs) 
{
    *this = int(*this) % rhs;
    return  *this;
}

const Coord& Coord::operator<<= (int rhs) 
{
    *this = *this << rhs;
    return  *this;
}

const Coord& Coord::operator>>= (int rhs) 
{
    *this = *this >>  rhs;
    return  *this;
}

const Coord& Coord::operator&= (const Coord& rhs) 
{
    *this = int(*this) & rhs;
    return  *this;
}

const Coord& Coord::operator^= (const Coord& rhs) 
{
    *this = int(*this) ^ rhs;
    return  *this;
}

const Coord& Coord::operator|= (const Coord& rhs) 
{
    *this = int(*this) | rhs;
    return  *this;
}

Coord& Coord::operator ++ ()
{
    *this = *this + 1;
    return  *this;
}

Coord& Coord::operator -- ()
{
    *this = *this - 1;
    return  *this;
}

char operator < (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i < rhs.value.i;
    case REAL:
	return (float(lhs) < float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

char operator <= (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i <= rhs.value.i;
    case REAL:
	return (float(lhs) <= float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

char operator > (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i > rhs.value.i;
    case REAL:
	return (float(lhs) > float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

char operator >= (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i >= rhs.value.i;
    case REAL:
	return (float(lhs) >= float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

char operator == (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i == rhs.value.i;
    case REAL:
	return (float(lhs) == float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

char operator != (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case INTEGER:
	return lhs.value.i != rhs.value.i;
    case REAL:
	return (float(lhs) != float(rhs));
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return 0;
    }
}

Coord Coord::promote (const NumericType type) const
{
    switch(type) {

    case INTEGER:
	return int(*this);
    case REAL:
	return float(*this);
    case NONE:
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
	return Coord();
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return Coord();
    }
}

ostream &operator<<(ostream &stream, Coord &coordinate)
{
    switch (coordinate.type()) {
    case INTEGER:
	stream << coordinate.value.i;
	break;
    case REAL:
	stream << coordinate.value.f;
	break;
    case NONE:
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
	break;
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	break;
    }
    return stream;

}

istream &operator>>(istream &stream, Coord &coordinate)
{
    char	buf[80];

    stream >> buf;
    // I absolutely hate unsafe input.
    // iostreams are gronkulously undocumented

    if (*buf) {
	coordinate = atoCoord(buf);
    } else
	coordinate = Coord();

    return stream;
}

Coord atoCoord(const char *s)
{
    const char	*p;
    NumericType	scanas = INTEGER;
    char	hex=0;
    int		len;

    // scan past initial whitespace
    while (*s && isspace(*s))
	s++;

    for (p=s; *p; p++) {
	if (hex ? isxdigit(*p) : isdigit(*p))
	    continue;
	else if (*p=='-')
	    continue;
	else if (*p=='.') {
	    scanas = REAL;
	    hex=0;
	    continue;
	} else if (*p=='x' && scanas==INTEGER) {
	    hex=1;
	    continue;
	} else if (isspace(*p)) {
	    break;
	} else if (*p=='e' || *p=='E'){
	    // we would have been removed by the first test if this
	    // were a hex number
	    scanas = REAL;
	    // hex already == 0; 
	    continue;
	} else {
	    scanas=NONE;
	    break;
	}
    }
    len = p-s;
    if (*p && isspace(*p))
	while (*p) {
	    if (!isspace(*p))
		return Coord();
	    p++;
	}
    switch(scanas) {
	int	urgh;
    case INTEGER:
	{
	    int	rval;
	    if (1==sscanf((char*)s,"%i%n", &rval, &urgh) && urgh==len)
		return rval;
	}
	return Coord();
	// ignore following comment

	// fall through and try to interpret it as a float
	// (4e5 would do this)
    case REAL:
	{
	    float	rval;
	    if (1==sscanf((char*)s,"%g%n", &rval, &urgh) && urgh==len)
		return rval;
	}
	// well phooey, we just failed all around.  Fall through.
    default:
	return Coord();
    }
}
@


1.22
log
@Added real Coord &operator= code, uncommented the ~Coord(). Just in case.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.21 92/06/28 05:19:30 fischer Exp Locker: fischer $";
d7 3
d117 1
a118 3
Coord::Coord(const Coord& coordinate)
{
    *this = coordinate;
a119 36
//     this->tag = coordinate.tag;    // this seems superfluous...is *this=coordinate ok?
//     switch (tag) {
//     case INTEGER:
// 	this->value.i = coordinate.value.i;
// 	break;
//     case REAL:
// 	this->value.f = coordinate.value.f;
// 	break;
//     case NONE:
// 	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
// 	break;
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//     }
}
// 
Coord& Coord::operator=(const Coord& coordinate)
{
//    *this = coordinate;
    
    this->tag = coordinate.tag;
    switch (tag) {
    case INTEGER:
	this->value.i = coordinate.value.i;
	break;
    case REAL:
	this->value.f = coordinate.value.f;
	break;
    case NONE:
	break;
    default:
	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
    }
    return *this;
}
    
a228 83
//  It was decided that operations that only make sense on integers
// would not be defined for Coords.  Coords may be implicitly converted
// to integers just as efficiently as we can do it in a member function.

// Coord operator% (const Coord &left,  const Coord &right)
// {
//     switch(IA::result_type(left.type(), right.type())) {
//     case INTEGER:
// 	return left.value.i % right.value.i;
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// 
// Coord operator~(const Coord& coordinate)
// {
//     switch(coordinate.tag) {
//     case INTEGER:
// 	return ~(coordinate.value.i);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// 
// Coord operator<<(const Coord& lhs, unsigned int shift)
// {
//     switch(lhs.type()) {
//     case INTEGER:
// 	return (lhs.value.i << shift);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// Coord operator>>(const Coord& lhs, unsigned int shift)
// {
//     switch(lhs.type()) {
//     case INTEGER:
// 	return (lhs.value.i >> shift);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// Coord operator&(const Coord& lhs, const Coord& rhs)
// {
//     switch(IA::result_type(lhs.type(), rhs.type())) {
//     case INTEGER:
// 	return (lhs.value.i & rhs.value.i);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// Coord operator^(const Coord& lhs, const Coord& rhs)
// {
//     switch(IA::result_type(lhs.type(), rhs.type())) {
//     case INTEGER:
// 	return (lhs.value.i ^ rhs.value.i);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }
// 
// Coord operator | (const Coord& lhs, const Coord& rhs)
// {
//     switch(IA::result_type(lhs.type(), rhs.type())) {
//     case INTEGER:
// 	return (lhs.value.i | rhs.value.i);
//     default:
// 	throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
//	return Coord();
//     }
// }

d255 1
a255 1
    *this = *this % rhs;
d273 1
a273 1
    *this = *this & rhs;
d279 1
a279 1
    *this = *this ^ rhs;
d285 1
a285 1
    *this = *this | rhs;
@


1.21
log
@Made promote accept const NumericType args, made it const member function.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.20 92/06/27 05:08:59 fischer Exp Locker: fischer $";
d7 3
d117 23
a139 1
    this->tag = coordinate.tag;    // this seems superfluous... why isn't *this=coordinate ok?
a147 1
	throw(IA::TYPE_UNSPECIFIED, __FILE__, __LINE__);
d152 1
a153 1

a406 5
// Do we need post- and pre-increment functions here?

// Doesn't matter for gcc 2.0: everything is pre-increment, it doesn't
// use the post-increment version at all.

a407 6
{
    *this = *this + 1;
    return  *this;
}

Coord& Coord::operator ++ (int dummy)
@


1.20
log
@Added Coord(cont Coord&) constructor, since gcc wasn't making
use of the default one it should have been.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.19 92/06/21 17:04:23 thoth Exp Locker: fischer $";
d7 4
d484 1
a484 1
Coord Coord::promote (NumericType type)
@


1.19
log
@fixed heinous infinite recursion error introduced during
throw robustification.  Operator int and float should now be repaired.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.18 92/06/17 15:38:59 thoth Exp Locker: thoth $";
d7 4
d108 19
d497 1
a497 1
ostream &operator<<(ostream &stream, Coord coordinate)
@


1.18
log
@fixed Coordinate input, duh
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.17 92/06/17 15:22:51 thoth Exp Locker: thoth $";
d7 3
d111 1
a111 1
	return Coord();
d114 1
a114 1
	return Coord();
d127 1
a127 1
	return Coord();
d130 1
a130 1
	return Coord();
@


1.17
log
@added input and string conversion operations.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.16 92/06/16 13:56:50 thoth Exp Locker: thoth $";
d7 3
d493 8
a500 5
    char	*s;
    stream.gets(&s);
    if (s) {
	coordinate = atoCoord(s);
	free(s);
@


1.16
log
@updated to follow new enum constant conventions
removed operations that only make sense on integers
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.15 92/06/10 11:55:32 thoth Exp Locker: thoth $";
d7 4
d94 2
d105 1
d108 1
d121 1
d124 1
a124 1
	
d143 1
d156 1
d169 1
d187 1
d190 1
d203 1
d218 1
d230 1
d242 1
d253 1
d264 1
d275 1
d286 1
d382 1
d395 1
d408 1
d421 1
d434 1
d447 1
d461 1
d464 1
d479 1
d482 1
d486 81
@


1.15
log
@updated some more, to reflect new conventions.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.14 92/06/09 12:26:41 fischer Exp Locker: thoth $";
d7 3
d87 1
a87 1
// Warning:  If Integer is not the ``minimum'' type, everything in
d95 1
a95 1
    case Integer:
d97 2
a98 2
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
d100 1
a100 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d107 1
a107 1
    case Integer:
d109 1
a109 1
    case Float:
d111 2
a112 2
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
d114 1
a114 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d119 5
a123 5
// Rob: please note that result_type() never returns None.
// So I removed your throw(IA::TypeUnspecified).   If it 
// *did* return none, it would indicate a TypeMismatch, anyway.
// If one of the types passed to result_type() is None, result_type() 
// itself throws the TypeMismatch error.
d128 1
a128 1
    case Integer:
d130 1
a130 1
    case Float:
d133 1
a133 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d140 1
a140 1
    case Integer:
d142 1
a142 1
    case Float:
d145 1
a145 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d152 1
a152 1
    case Integer:
d154 1
a154 1
    case Float:
d157 1
a157 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d161 1
a161 1
// N.B. Unary minus needs to check for uninitialized values (type==None) itself,
d163 1
a163 1
// result_type() throws IA::TypeUnspecified if it gets None, or finds no common
d169 1
a169 1
    case Integer:
d171 1
a171 1
    case Float:
d173 2
a174 2
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
d176 1
a176 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d183 1
a183 1
    case Integer:
d185 1
a185 1
    case Float:
d188 1
a188 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d192 3
a194 9
Coord operator% (const Coord &left,  const Coord &right)
{
    switch(IA::result_type(left.type(), right.type())) {
    case Integer:
	return left.value.i % right.value.i;
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}
d196 71
a267 61
Coord operator~(const Coord& coordinate)
{
    switch(coordinate.tag) {
    case Integer:
	return ~(coordinate.value.i);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}


Coord operator<<(const Coord& lhs, unsigned int shift)
{
    switch(lhs.type()) {
    case Integer:
	return (lhs.value.i << shift);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}

Coord operator>>(const Coord& lhs, unsigned int shift)
{
    switch(lhs.type()) {
    case Integer:
	return (lhs.value.i >> shift);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}

Coord operator&(const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case Integer:
	return (lhs.value.i & rhs.value.i);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}

Coord operator^(const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case Integer:
	return (lhs.value.i ^ rhs.value.i);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}

Coord operator | (const Coord& lhs, const Coord& rhs)
{
    switch(IA::result_type(lhs.type(), rhs.type())) {
    case Integer:
	return (lhs.value.i | rhs.value.i);
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
    }
}

d329 1
d354 1
a354 1
    case Integer:
d356 1
a356 1
    case Float:
d359 1
a359 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d366 1
a366 1
    case Integer:
d368 1
a368 1
    case Float:
d371 1
a371 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d378 1
a378 1
    case Integer:
d380 1
a380 1
    case Float:
d383 1
a383 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d390 1
a390 1
    case Integer:
d392 1
a392 1
    case Float:
d395 1
a395 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d402 1
a402 1
    case Integer:
d404 1
a404 1
    case Float:
d407 1
a407 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d414 1
a414 1
    case Integer:
d416 1
a416 1
    case Float:
d419 1
a419 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d427 1
a427 1
    case Integer:
d429 1
a429 1
    case Float:
d431 2
a432 2
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
d434 1
a434 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d441 1
a441 1
    case Integer:
d444 1
a444 1
    case Float:
d447 2
a448 2
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
d450 1
a450 1
	throw(IA::TypeMismatch, __FILE__, __LINE__);
@


1.14
log
@Made most Coord operators non-member friends to get 
automatic type coercion.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.13 92/06/08 02:48:25 fischer Exp Locker: fischer $";
d7 4
d87 1
a87 1
#include <Coord.h>
@


1.13
log
@Simplified switch statements (removed Complex: and Rational:
cases).  No extra break statements needed to be added (stylistic
nit). Since Integer is the base type,  removed most calls to
int(foo) $ int(bar)  where $ is some binary op,  replacing them
with foo.value.i & bar.value.i.  This should result in substantial
savings,  but will necessitate careful rewrite should a ``lower''
type such as Char or Boolean be added to Coord.
@
text
@d3 1
a3 1
static char rcsid[] = "$Id: Coord.cc,v 1.12 92/06/02 01:47:29 fischer Exp Locker: fischer $";
d7 9
d80 3
d118 1
a118 1
Coord Coord::operator+ (const Coord &right) const
d120 1
a120 1
    switch(IA::result_type(this->type(), right.type())) {
d122 1
a122 1
	return this->value.i + right.value.i;
d124 1
a124 1
	return float(*this) + float(right);
d130 1
a130 1
Coord Coord::operator* (const Coord &right) const
d132 1
a132 1
    switch(IA::result_type(this->type(), right.type())) {
d134 1
a134 1
	return this->value.i * right.value.i;
d136 1
a136 1
	return float(*this) * float(right);
d142 1
a142 1
Coord Coord::operator- (const Coord &right) const
d144 1
a144 1
    switch(IA::result_type(this->type(), right.type())) {
d146 1
a146 1
	return this->value.i - right.value.i;
d148 1
a148 1
	return float(*this) - float(right);
d159 1
a159 1
Coord Coord::operator- () const
d161 1
a161 1
    switch(this->type()) {
d163 1
a163 1
	return -this->value.i;
d165 1
a165 1
	return -this->value.f;
d173 1
a173 1
Coord Coord::operator/ (const Coord &right) const
d175 1
a175 1
    switch(IA::result_type(this->type(), right.type())) {
d177 1
a177 1
	return this->value.i / right.value.i;
d179 1
a179 1
	return float(*this) / float(right);
d185 1
a185 1
Coord Coord::operator% (const Coord &right) const
d187 1
a187 1
    switch(IA::result_type(this->type(), right.type())) {
d189 1
a189 1
	return this->value.i % right.value.i;
d196 1
a196 1
Coord Coord::operator~() const
d198 1
a198 1
    switch(this->type()) {
d200 1
a200 1
	return ~(this->value.i);
d207 1
a207 1
Coord Coord::operator<<(int shift) const
d209 1
a209 1
    switch(this->type()) {
d211 1
a211 1
	return (this->value.i << shift);
d217 1
a217 1
Coord Coord::operator>>(int shift) const
d219 1
a219 1
    switch(this->type()) {
d221 1
a221 1
	return (this->value.i >> shift);
d227 1
a227 1
Coord Coord::operator&(const Coord& foo) const
d229 1
a229 1
    switch(IA::result_type(this->type(), foo.type())) {
d231 1
a231 1
	return (this->value.i & foo.value.i);
d237 1
a237 1
Coord Coord::operator^(const Coord& foo) const
d239 1
a239 1
    switch(IA::result_type(this->type(), foo.type())) {
d241 1
a241 1
	return (this->value.i ^ foo.value.i);
d247 1
a247 1
Coord Coord::operator | (const Coord& foo) const
d249 1
a249 1
    switch(IA::result_type(this->type(), foo.type())) {
d251 1
a251 1
	return (this->value.i | foo.value.i);
d318 2
a319 1
// Doesn't matter for gcc 2.0: everything is pre-increment.
@


1.12
log
@Made assignment operators const Coord&.  Removed 
Removed !, &&, and ||.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.11 92/05/27 07:45:07 fischer Exp Locker: fischer $";
d3 2
d7 4
a77 4
    case Float:
	return int(value.f);
    case Rational:
    case Complex:
d80 2
a91 3
    case Rational:
    case Complex:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d94 3
a99 20
// Here we try to get around busted operator overloading
// by using operator+ declared as a fiend.  Still doesn't 
// work in gcc-2.1,  though both methods work in gcc-2.0.

// Coord operator+ (const Coord& left, const Coord& right)
// {
//   switch(IA::result_type(left.type(), right.type())){
//   case Integer:
//     return int(left) + int(right);
//   case Float:
//     return float(left) + float(right);
//   case Rational:
//   case Complex:
//     throw(IA::TypeMismatch, __FILE__, __LINE__);
//   case None:
//     throw(IA::TypeUnspecified, __FILE__, __LINE__);
//   }
// }


d110 1
a110 1
	return int(*this) + int(right);
a112 2
    case Rational:
    case Complex:
d122 1
a122 1
	return int(*this) * int(right);
a124 2
    case Rational:
    case Complex:
d134 1
a134 1
	return int(*this) - int(right);
a136 2
    case Rational:
    case Complex:
d142 4
a145 1
// N.B. This needs to check for uninitialized values itself.
d151 1
a151 1
	return -int(*this);
d153 1
a153 1
	return -float(*this);
a155 2
    case Rational:
    case Complex:
d165 1
a165 1
	return int(*this) / int(right);
a167 2
    case Rational:
    case Complex:
d177 1
a177 4
	return int(*this) % int(right);
    case Float:
    case Rational:
    case Complex:
a304 1

d306 1
d314 6
d330 1
a330 1
	return (int(lhs) < int(rhs));
a332 2
    case Rational:
    case Complex:
d342 1
a342 1
	return (int(lhs) <= int(rhs));
a344 2
    case Rational:
    case Complex:
d354 1
a354 1
	return (int(lhs) > int(rhs));
a356 2
    case Rational:
    case Complex:
d366 1
a366 1
	return (int(lhs) >= int(rhs));
a368 2
    case Rational:
    case Complex:
d378 1
a378 1
	return (int(lhs) == int(rhs));
a380 2
    case Rational:
    case Complex:
d390 1
a390 1
	return (int(lhs) != int(rhs));
a392 2
    case Rational:
    case Complex:
a397 38
// Deprecated?
// 
// char operator ! (const Coord& coord)
// {
//     return ! (coord == 0);
// }

// Using member functions below messes the C++ && and ||
// semantics.  See notes below and in Coord.h.
// 
// char operator || (const Coord& lhs)
// {
//     return (lhs != 0);
// }
// 
// char operator && (const Coord& lhs)
// {
//     return (lhs != 0);
// }
// 
// These will not work -- rhs is always evaluated (gcc 2.0, sparc).
//  
// char operator || (const Coord& lhs, const Coord& rhs)
// {
//     if (lhs == 0)
// 	return (rhs != 0);
//     else
// 	return 1;
// }
// 
// char operator && (const Coord& lhs, const Coord& rhs)
// {
//     if (lhs == 0)
// 	return 0;
//     else
// 	return (rhs != 0);
// }

d401 1
a401 3
	
	// user wants an integer.
	
d403 1
a403 9
	switch(this->type()) {
	case Integer:
	    return int(*this);
	default:
	    throw(IA::TypeMismatch, __FILE__, __LINE__);
	}
	
	// user wants a float.
	
d405 3
a407 7
	switch(this->type()) {
	case Integer:
	case Float:
	    return float(*this);
	default:
	    throw(IA::TypeMismatch, __FILE__, __LINE__);
	}
a412 11
//
// This is currently broken in gcc 2.1, output does not 
// seem to type cast correctly.  Until gcc 2.x fixes it,
// we can use the Coord.output(ostream&) call.
//
// Currently using gcc 2.0, which gets overloading correct.
// Used to be:
// void Coord::output(ostream &o) const
// 


a423 2
    case Complex:
    case Rational:
@


1.11
log
@Added && and || as one arg friend functions, which is
only way to preserve special semantics. Added bitwise
compound assignment.  Changed bitwise operators to work
between Coords, except for shift operators which now
use signed ints.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.11 1992/05/26 11:30:30 fischer Exp fischer $";
d4 8
a11 1
// $Log: Coord.cc,v $
d271 1
a271 1
Coord& Coord::operator += (const Coord& rhs) 
d277 1
a277 1
Coord& Coord::operator -= (const Coord& rhs) 
d283 1
a283 1
Coord& Coord::operator *= (const Coord& rhs) 
d289 1
a289 1
Coord& Coord::operator /= (const Coord& rhs) 
d295 1
a295 1
Coord& Coord::operator %= (const Coord& rhs) 
d301 1
a301 1
Coord& Coord::operator<<= (int rhs) 
d307 1
a307 1
Coord& Coord::operator>>= (int rhs) 
d313 1
a313 1
Coord& Coord::operator&= (const Coord& rhs) 
d319 1
a319 1
Coord& Coord::operator^= (const Coord& rhs) 
d325 1
a325 1
Coord& Coord::operator|= (const Coord& rhs) 
d430 6
a435 4
char operator ! (const Coord& coord)
{
    return ! (coord == 0);
}
d439 11
a449 13
// Unfortunately, using this form seems to keep float Coord from 
// being properly evaluated (they are instead first cast to ints).

char operator || (const Coord& lhs)
{
    return (lhs != 0);
}

char operator && (const Coord& lhs)
{
    return (lhs != 0);
}

@


1.10
log
@*** empty log message ***
@
text
@d214 1
a214 1
Coord Coord::operator<<(unsigned int shift) const
d224 1
a224 1
Coord Coord::operator>>(unsigned int shift) const
d234 1
a234 1
Coord Coord::operator&(unsigned int foo) const
d236 1
a236 1
    switch(this->type()) {
d238 1
a238 1
	return (this->value.i & foo);
d244 1
a244 1
Coord Coord::operator^(unsigned int foo) const
d246 1
a246 1
    switch(this->type()) {
d248 1
a248 1
	return (this->value.i ^ foo);
d254 1
a254 1
Coord Coord::operator|(unsigned int foo) const
d256 1
a256 1
    switch(this->type()) {
d258 1
a258 1
	return (this->value.i | foo);
d294 31
d428 4
d433 28
d465 1
a465 1
	// user wants an integer, damn it.
@


1.9
log
@Got overloading to work by simple expedient of using math.ufl.edu
version of g++:  gcc-2.0.  
Changed Coord arithmetic operators to assume result_type()
is taking care of uninitialized Coord types (tag==None) via throw.
Added default: to switches so Rob can rest easy about new 
NumericTypes.  Added *,/,+,%,-.  Lots more to go. Since we now
have NumericType abstraction,  changed stuff like this->tag to
this->type():  because these are inline functions, there should be little 
overhead, but we need to check with some timing tests.
Changed Coord.val name to Coord.value name since I can never remember
these damn c-style abbreviations.   .
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.8 92/05/21 20:24:10 thoth Exp Locker: fischer $";
d4 23
a26 1
// $Log:	Coord.cc,v $
d65 2
a68 2
    case Float:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d74 1
a74 1
Coord::operator float() const
d202 225
d430 1
a430 1
// use the Coord.output(ostream&) call.
d432 4
a435 3
// ostream &operator<<(ostream &o, Coord c)
// {
//    Coord *that = &c;
d437 2
a438 1
void Coord::output(ostream &o) const
d440 1
a440 1
    switch (this->tag) {
d442 1
a442 1
	o << this->value.i;
d445 1
a445 1
	o << this->value.f;
d447 2
d451 2
a452 4
    case None:
	throw(IA::TypeUnspecified, __FILE__, __LINE__);
	//default:
	//throw(IA::TypeMismatch, __FILE__, __LINE__);
d454 2
@


1.8
log
@switched to // comments for rcs log
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.7 92/05/21 15:09:52 thoth Exp Locker: thoth $";
d5 3
d38 1
a38 1
int Coord:: operator int() const
d42 1
a42 1
	return val.i;
d45 2
a48 2
    case Float:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d52 1
a52 1
Coord:: operator float() const
d56 1
a56 1
	return this->val.i;
d58 1
a58 1
	return this->val.f;
d61 1
a63 2
	//default:
	//throw(IA::TypeMismatch, __FILE__, __LINE__);
d67 27
a93 2
//Coord Coord::operator+ (const Coord &right) const
Coord Coord::plus (const Coord &right) const
d95 1
a95 3
    NumericType	result;
    result = IA::result_type(this->tag, right.tag);
    switch(result) {
a97 1

d100 6
d107 7
d116 28
d146 4
d153 13
d167 13
d193 1
a193 1
	o << this->val.i;
d196 1
a196 1
	o << this->val.f;
@


1.7
log
@add addition operator.  Use of this operator
causes the compiler to hang.
declared some methods const (unmodifying).
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.6 92/05/21 12:05:50 thoth Exp Locker: thoth $";
d3 29
a31 24
/*
 * $Log:	Coord.cc,v $
 * Revision 1.6  92/05/21  12:05:50  thoth
 * added handling for new NumericTypes.
 * 
 * Revision 1.5  92/05/21  08:06:47  fischer
 * Started rework of CoordType to IA::NumericType
 * so all classes can access.
 * 
 * Revision 1.4  92/05/20  06:30:35  fischer
 * created a scheme to get around thoth's scheme:
 * removed it.
 * 
 * Revision 1.3  92/05/18  15:15:00  thoth
 * created a scheme to get around g++2.1's busted overloading
 * and type conversion.
 * 
 * Revision 1.2  92/05/16  13:57:25  thoth
 * added log goo
 * 
 * Revision 1.1  92/05/16  13:46:19  thoth
 * Initial revision
 *
 */
@


1.6
log
@added handling for new NumericTypes.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.5 92/05/21 08:06:47 fischer Exp Locker: thoth $";
d5 3
d30 1
a30 1
int Coord:: operator int()
d44 1
a44 1
Coord:: operator float()
d60 8
a67 4
// Coord:: operator + (const Coord & left, const Coord & right)
// {
//     
// }
d69 2
d72 8
d89 1
a89 1
void Coord::output(ostream &o)
@


1.5
log
@Started rework of CoordType to IA::NumericType
so all classes can access.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.4 92/05/20 06:30:35 fischer Exp Locker: fischer $";
d5 4
d32 2
d48 2
d52 2
a53 2
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
d81 2
d85 2
a86 2
    default:
	throw(IA::TypeMismatch, __FILE__, __LINE__);
a88 5


// Local variables:
// eval: (joe-style)
// End:
@


1.4
log
@created a scheme to get around thoth's scheme:
removed it.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.3 92/05/18 15:15:00 thoth Exp Locker: fischer $";
d5 4
d23 1
a23 1
Coord:: operator int()
d49 11
d79 1
@


1.3
log
@created a scheme to get around g++2.1's busted overloading
and type conversion.
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.2 92/05/16 13:57:25 thoth Exp Locker: thoth $";
d5 4
a18 1
#if OVERLOADINGWORKS
a19 3
#else
int Coord::to_int()
#endif
a30 1
#if OVERLOADINGWORKS
a31 3
#else
float Coord::to_float()
#endif
d33 1
a33 1
    switch (tag) {
d35 1
a35 1
	return val.i;
d37 1
a37 1
	return val.f;
d40 2
a41 2
	// default:
	// throw(IA::TypeMismatch, __FILE__, __LINE__);
d45 4
a48 5
#if OVERLOADINGWORKS
ostream &operator<<(ostream &o, Coord c)
{
    Coord *that = &c;
#else
d51 1
a51 3
    Coord *that = this;
#endif
    switch (that->tag) {
d53 1
a53 1
	o << that->val.i;
d56 1
a56 1
	o << that->val.f;
d60 2
a61 2
	//default:
	//throw(IA::TypeMismatch, __FILE__, __LINE__);
a62 3
#if OVERLOADINGWORKS
    return o;
#endif
@


1.2
log
@added log goo
@
text
@d1 1
a1 1
static char rcsid[] = "$Id: Coord.cc,v 1.1 92/05/16 13:46:19 thoth Exp Locker: thoth $";
d5 3
d15 3
d19 1
d31 3
d35 1
d49 1
d52 7
a58 1
    switch (c.tag) {
d60 1
a60 1
	o << c.val.i;
d63 1
a63 1
	o << c.val.f;
d70 1
d72 1
@


1.1
log
@Initial revision
@
text
@d1 1
a1 1
static char rcsid[] = "$Id$";
d4 3
a6 1
 * $Log$
@
