Mail Archives: djgpp/2002/02/27/20:47:27
X-Authentication-Warning: | delorie.com: mailnull set sender to djgpp-bounces using -f
|
From: | "Traveler" <traveler AT netti DOT fi>
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Developing alternative for some parts of STL. Very, very, very alpha :)
|
Date: | Thu, 28 Feb 2002 03:51:14 +0200
|
Organization: | SAUNALAHDEN asiakas
|
Lines: | 453
|
Message-ID: | <a5k1ql$mib$1@tron.sci.fi>
|
NNTP-Posting-Host: | dccl.tdyn.saunalahti.fi
|
X-Trace: | tron.sci.fi 1014860438 23115 195.197.80.250 (28 Feb 2002 01:40:38 GMT)
|
X-Complaints-To: | newsmaster AT saunalahti DOT fi
|
NNTP-Posting-Date: | 28 Feb 2002 01:40:38 GMT
|
X-Priority: | 3
|
X-MSMail-Priority: | Normal
|
X-Newsreader: | Microsoft Outlook Express 5.50.4807.1700
|
X-MimeOLE: | Produced By Microsoft MimeOLE V5.50.4807.1700
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Reply-To: | djgpp AT delorie DOT com
|
Hi
I know that I am asking for trouble while posting this stuff but I post it
anyway (I just love to read all those flames...sight !)
Note that the following is just an very basic model trying to mimic the STL.
There is no iterator classes (which I hate sooooo much !) and maybe never
will be unless I cannot device another way....
Okay, now here is my simple, no error checking including buggy code that
tries to mimic function-objects:
BTW, look at the declaration of the "Plus<Type>" class on how I tried to
handle the value overflow & underflow....
#ifndef __FUNCTION_H
#define __FUNCTION_H
template <typename Type>
class And;
template <typename Type>
class ArithmeticFunction;
template <typename Type>
class CompareFunction;
template <typename Type>
class Divide;
template <typename Type>
class Equal;
template <typename returnType,typename arg1,typename arg2,typename arg3>
class Function;
template <typename Type>
class Greater;
template <typename Type>
class GreaterOrEqual;
template <typename Type>
class Less;
template <typename Type>
class LessOrEqual;
template <typename Type>
class LogicalFunction;
template <typename Type>
class Minus;
template <typename Type>
class Modulo;
template <typename Type>
class Multiply;
template <typename Type>
class Negation;
template <typename Type>
class Not;
template <typename Type>
class NotEqual;
template <typename Type>
class Number;
template <typename Type>
class Or;
template <typename Type>
class Plus;
// Global function(s)
template <typename Type,int n>
inline void BubbleSort(Type (&table)[n],const CompareFunction<Type>&
function = Greater<Type>());
// Lots of more sorting functions coming later...
template <typename Type,int n>
inline Type& Max(Type (&table)[n]);
template <typename Type>
inline Type& Max(Type& a,Type& b);
template <typename Type>
inline const Type& Max(const Type& a,const Type& b);
template <typename Type,int n>
inline Type& Min(Type (&table)[n]);
template <typename Type>
inline Type& Min(Type& a,Type& b);
template <typename Type>
inline const Type& Min(const Type& a,const Type& b);
template <typename Type,int n>
inline unsigned long Length(Type (&table)[n]);
template <typename Type>
inline void Swap(Type& a,Type& b);
// a AND b
template <typename Type>
class And : public LogicalFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (x & y);}
Type operator()(const Type& a,const Type& b) {return (x & y);}
};
// Abstract base class for arithmetic functions
template <typename Type>
class ArithmeticFunction
{
public:
virtual Type operator()(const Type& a,const Type& b)const=0;
virtual Type operator()(const Type& a,const Type& b)=0;
};
// Abstract base class for comparing functions
// Here the return type of the function is easy enough because it will
allways be of type "bool".
// Further, subtype of CompareFunction cannot never be unary.
// How can you compare something to nothing ??? :=)
// With other classes the return type needs further checking and I think
that I must use
// multiple inheritance in some parts...hmmmmm
template <typename Type>
class CompareFunction
{
public:
virtual bool operator()(const Type& a,const Type& b)const=0;
virtual bool operator()(const Type& a,const Type& b)=0;
};
// a / b
template <typename Type>
class Divide : public ArithmeticFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (a/b);}
Type operator()(const Type& a,const Type& b) {return (a/b);}
};
// a == b
template <typename Type>
class Equal : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a == b);}
bool operator()(const Type& a,const Type& b) {return (a == b);}
};
// Base class for functions
// This will become the "father" of all function classes
// If it will be used through single inheritance, multi-inheritance, and
abstract or not is
// left to the future...
// Currently, "child" classes must be maked error free and after that the
common functionality and those things that MUST be in the base class are
moved here...
// This class is screaming template specialization for number of arguments
it can have :)
template <typename returnType,typename arg1,typename arg2,typename arg3>
class Function
{
public:
};
// a > b
template <typename Type>
class Greater : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a > b);}
bool operator()(const Type& a,const Type& b) {return (a > b);}
};
// a >= b
template <typename Type>
class GreaterOrEqual : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a >= b);}
bool operator()(const Type& a,const Type& b) {return (a >= b);}
};
// a < b
template <typename Type>
class Less : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a < b);}
bool operator()(const Type& a,const Type& b) {return (a < b);}
};
// a <= b
template <typename Type>
class LessOrEqual : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a <= b);}
bool operator()(const Type& a,const Type& b) {return (a <= b);}
};
// Abstract base class for logical functions
// Yeah, I know. I have forgotten the binary relatives of these functions
but currently that is the least of my problems...
template <typename Type>
class LogicalFunction
{
public:
virtual Type operator()(const Type& a,const Type& b)const=0;
virtual Type operator()(const Type& a,const Type& b)=0;
};
// a - b
template <typename Type>
class Minus : public ArithmeticFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (a - b);}
Type operator()(const Type& a,const Type& b) {return (a - b);}
};
// a % b
template <typename Type>
class Modulo : public ArithmeticFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (a % b);}
Type operator()(const Type& a,const Type& b) {return (a % b);}
};
// a * b
template <typename Type>
class Multiply : public ArithmeticFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (a * b);}
Type operator()(const Type& a,const Type& b) {return (a * b);}
};
// -a
template <typename Type>
class Negation : public ArithmeticFunction<Type>
{
public:
Type operator()(const Type& a)const {return -a;}
Type operator()(const Type& a) {return -a;}
};
// NOT a
template <typename Type>
class Not : public LogicalFunction<Type>
{
public:
Type operator()(const Type& a)const {return !a;}
Type operator()(const Type& a) {return !a;}
};
// a != b
template <typename Type>
class NotEqual : public CompareFunction<Type>
{
public:
bool operator()(const Type& a,const Type& b)const {return (a != b);}
bool operator()(const Type& a,const Type& b) {return (a != b);}
};
// Base class for number types (currently for integers only)
template <typename Type>
class Number
{
public:
static const Type MIN_VALUE;
static const Type MAX_VALUE;
};
template <typename Type>
const Type Number<Type>::MIN_VALUE = 0;
template <typename Type>
const Type Number<Type>::MAX_VALUE = ~Number<Type>::MIN_VALUE;
const signed char Number<signed char>::MIN_VALUE = -128;
const signed char Number<signed char>::MAX_VALUE = ~Number<signed
char>::MIN_VALUE;
const char Number<char>::MIN_VALUE = -128;
const char Number<char>::MAX_VALUE = ~Number<char>::MIN_VALUE;
const short Number<short>::MIN_VALUE = -32768;
const short Number<short>::MAX_VALUE =
~Number<short>::MIN_VALUE;
const int Number<int>::MIN_VALUE = -2147483647;
const int Number<int>::MAX_VALUE = ~Number<int>::MIN_VALUE;
const long Number<long>::MIN_VALUE = -2147483647;
const long Number<long>::MAX_VALUE = ~Number<long>::MIN_VALUE;
// a OR b
template <typename Type>
class Or : public LogicalFunction<Type>
{
public:
Type operator()(const Type& a,const Type& b)const {return (a | b);}
Type operator()(const Type& a,const Type& b) {return (a | b);}
};
// a + b
template <typename Type>
class Plus : public ArithmeticFunction<Type>
{
public:
// Exception classe(s). If "Plus" class has these then should the "Minus"
have them as well which
// leads to the conclusion that originally they should be moved to
"ArithmeticFunction" class
// No functionally yet...
class Overflow
{
public:
};
class Underflow
{
public:
};
Type operator()(const Type& a,const Type& b)const throw(const
Overflow&,const Underflow&)
{
if((Max(a,b) - Min(a,b)) < Number<Type>::MAX_VALUE)
throw Overflow();
else
if((Min(a,b) - Max(a,b)) > Number<Type>::MIN_VALUE)
throw Underflow();
else
return (a + b);
}
Type operator()(const Type& a,const Type& b) throw(const
Overflow&,const Underflow&)
{
if((Max(a,b) - Min(a,b)) < Number<Type>::MAX_VALUE)
throw Overflow();
else
if((Min(a,b) - Max(a,b)) > Number<Type>::MIN_VALUE)
throw Underflow();
else
return (a + b);
}
};
template <typename Type,int n>
void BubbleSort(Type (&table)[n],const CompareFunction<Type>& function)
{
unsigned long index = 0,
passes = 1;
bool exchange = true;
for(;passes < n && exchange;passes++)
{
exchange = false;
for(index = 0;index < (n - passes);index++)
if(function(table[index],table[index+1]))
{
Swap(table[index],table[index+1]);
exchange = true;
}
}
}
template <typename Type,int n>
Type& Max(Type (&table)[n])
{
Greater<Type> function;
unsigned long max = 0;
for(unsigned long index = 1;index < n;index++)
if(function(table[index],table[max]))
max = index;
return table[max];
}
template <typename Type>
Type& Max(Type& a,Type& b)
{
Greater<Type> function;
return function(a,b) ? a : b;
}
template <typename Type>
const Type& Max(const Type& a,const Type& b)
{
Greater<Type> function;
return function(a,b) ? a : b;
}
template <typename Type,int n>
Type& Min(Type (&table)[n])
{
Less<Type> function;
unsigned long min = 0;
for(unsigned long index = 1;index < n;index++)
if(function(table[index],table[min]))
min = index;
return table[min];
}
template <typename Type>
Type& Min(Type& a,Type& b)
{
Less<Type> function;
return function(a,b) ? a : b;
}
template <typename Type>
const Type& Min(const Type& a,const Type& b)
{
Less<Type> function;
return function(a,b) ? a : b;
}
template <typename Type,int n>
unsigned long Length(Type (&table)[n]) {return n;}
template <typename Type>
void Swap(Type& a,Type& b)
{
Type tmp = a;
a = b;
b = tmp;
}
// Little test....
#include <iostream>
#include "function.h"
int main(int argc,char* argv[])
{
using namespace std;
short table[] = {24,-12,43,-1,32767,-32768};
BubbleSort(table);
for(int index = 0;index < Length(table);index++)
cout << table[index] << endl;
Plus<short> function;
try
{
//cout << table[Length(table)-1] << " + " << 1 << " = " <<
function(table[Length(table)-1],1) << endl;
cout << table[0] << " + " << -1 << " = " <<
function(table[0],-1) << endl;
}
catch(const Plus<short>::Overflow& exception)
{
cout << "Overflow!\n";
}
catch(const Plus<short>::Underflow& exception)
{
cout << "Underflow!\n";
}
return(0);
}
#endif
Traveler
traveler AT netti DOT fi
- Raw text -