X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-bounces using -f From: "Traveler" 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: 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" class on how I tried to handle the value overflow & underflow.... #ifndef __FUNCTION_H #define __FUNCTION_H template class And; template class ArithmeticFunction; template class CompareFunction; template class Divide; template class Equal; template class Function; template class Greater; template class GreaterOrEqual; template class Less; template class LessOrEqual; template class LogicalFunction; template class Minus; template class Modulo; template class Multiply; template class Negation; template class Not; template class NotEqual; template class Number; template class Or; template class Plus; // Global function(s) template inline void BubbleSort(Type (&table)[n],const CompareFunction& function = Greater()); // Lots of more sorting functions coming later... template inline Type& Max(Type (&table)[n]); template inline Type& Max(Type& a,Type& b); template inline const Type& Max(const Type& a,const Type& b); template inline Type& Min(Type (&table)[n]); template inline Type& Min(Type& a,Type& b); template inline const Type& Min(const Type& a,const Type& b); template inline unsigned long Length(Type (&table)[n]); template inline void Swap(Type& a,Type& b); // a AND b template class And : public LogicalFunction { 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 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 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 class Divide : public ArithmeticFunction { 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 class Equal : public CompareFunction { 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 class Function { public: }; // a > b template class Greater : public CompareFunction { 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 class GreaterOrEqual : public CompareFunction { 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 class Less : public CompareFunction { 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 class LessOrEqual : public CompareFunction { 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 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 class Minus : public ArithmeticFunction { 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 class Modulo : public ArithmeticFunction { 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 class Multiply : public ArithmeticFunction { 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 class Negation : public ArithmeticFunction { public: Type operator()(const Type& a)const {return -a;} Type operator()(const Type& a) {return -a;} }; // NOT a template class Not : public LogicalFunction { public: Type operator()(const Type& a)const {return !a;} Type operator()(const Type& a) {return !a;} }; // a != b template class NotEqual : public CompareFunction { 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 class Number { public: static const Type MIN_VALUE; static const Type MAX_VALUE; }; template const Type Number::MIN_VALUE = 0; template const Type Number::MAX_VALUE = ~Number::MIN_VALUE; const signed char Number::MIN_VALUE = -128; const signed char Number::MAX_VALUE = ~Number::MIN_VALUE; const char Number::MIN_VALUE = -128; const char Number::MAX_VALUE = ~Number::MIN_VALUE; const short Number::MIN_VALUE = -32768; const short Number::MAX_VALUE = ~Number::MIN_VALUE; const int Number::MIN_VALUE = -2147483647; const int Number::MAX_VALUE = ~Number::MIN_VALUE; const long Number::MIN_VALUE = -2147483647; const long Number::MAX_VALUE = ~Number::MIN_VALUE; // a OR b template class Or : public LogicalFunction { 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 class Plus : public ArithmeticFunction { 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::MAX_VALUE) throw Overflow(); else if((Min(a,b) - Max(a,b)) > Number::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::MAX_VALUE) throw Overflow(); else if((Min(a,b) - Max(a,b)) > Number::MIN_VALUE) throw Underflow(); else return (a + b); } }; template void BubbleSort(Type (&table)[n],const CompareFunction& 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 Type& Max(Type (&table)[n]) { Greater 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 Type& Max(Type& a,Type& b) { Greater function; return function(a,b) ? a : b; } template const Type& Max(const Type& a,const Type& b) { Greater function; return function(a,b) ? a : b; } template Type& Min(Type (&table)[n]) { Less 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 Type& Min(Type& a,Type& b) { Less function; return function(a,b) ? a : b; } template const Type& Min(const Type& a,const Type& b) { Less function; return function(a,b) ? a : b; } template unsigned long Length(Type (&table)[n]) {return n;} template void Swap(Type& a,Type& b) { Type tmp = a; a = b; b = tmp; } // Little test.... #include #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 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::Overflow& exception) { cout << "Overflow!\n"; } catch(const Plus::Underflow& exception) { cout << "Underflow!\n"; } return(0); } #endif Traveler traveler AT netti DOT fi