www.delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019