/* Example programs from the book Scientific and Engineering Programming in C++: An Introduction with Advanced Techniques and Examples, Addison-Wesley, 1994. (c) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 1994. ALL RIGHTS RESERVED. See README file for further details. */ #ifndef FunctionH #define FunctionH #include "Function/Functional.h" #include "SciEng/Fallible.h" #include "SciEng/Ptrs.h" class UnsetPtrErr : public SciEngErr { public: virtual String message() const; }; template class Function : public virtual Functional { public: Function( Range (*f)(Domain) ) : pf(f) {} Function() : pf(unsetPtrErr) {} const Function& operator=(const Function& f) { pf = f.pf; return *this; } const Function& operator=(Range (*f)(Domain)) { pf = f; return *this; } virtual Range operator()(const Domain& x) const { return pf(x); } virtual Function* clone() const { return new Function(*this); } static Range unsetPtrErr(Domain); // Throws UnsetPtrErr protected: Range (*pf)(Domain); }; template class IsoFunction : public virtual IsoFunctional, private Function { public: IsoFunction( Domain(*f)(Domain) ): Function(f) {} Function::operator(); virtual IsoFunction* clone() const { return new IsoFunction(*this); } }; template class Function2 : public virtual Functional2 { public: Function2 ( Range (*f)(Domain, Domain) ) : pf(f) {} virtual Range operator()(const Domain& x1, const Domain& x2) const { return (*pf)(x1, x2); } protected: Range(*pf)(Domain, Domain); }; template class IsoFunction2 : public virtual IsoFunctional2, public Function2 { public: IsoFunction2( Domain(*f)(Domain, Domain) ): Function2(f) {} }; template class FunctionOfRef : public virtual Functional { public: FunctionOfRef( Range (*f)(const Domain&) ) : pf(f) {} FunctionOfRef() : pf(unsetPtrErr) {} const FunctionOfRef& operator=( Range (*f)(const Domain&) ) { pf = f; return *this; } const FunctionOfRef& operator=( const FunctionOfRef& f ) { pf = f.pf; return *this; } virtual Range operator()(const Domain& x) const { return (*pf)(x); } virtual FunctionOfRef* clone() const { return new FunctionOfRef(*this); } static Range unsetPtrErr(const Domain&); // Throws UnsetPtrErr protected: Range (*pf)(const Domain&); }; template Range FunctionOfRef::unsetPtrErr(const Domain&) { throw UnsetPtrErr(); return *(Range*)0; // gotta fool a compiler... } template Range Function::unsetPtrErr(Domain) { throw UnsetPtrErr(); return *(Range*)0; // gotta fool a compiler... } template class ConversionFunctional : public virtual Functional { public: virtual Range operator()(const Domain& x) const {return Range(x);} }; template class VoidFunction : public Function { public: VoidFunction( D(*f)(D) ):Function(f){} void operator()(const D& x) const { (*pf)(x);} protected: void (*pf)(D) ; }; #include "SciEng/Boolean.h" #include "SciEng/SciEngErr.h" #include "SciEng/EquivalentCategory.h" template class CheckedFunction : public virtual Functional, public EquivalentCategory< CheckedFunction > { public: typedef R (*FunctionType)(const D&); CheckedFunction ( FunctionType f ) : pf(f){ if(f==0) pf.invalidate(); } CheckedFunction () : pf() {} void operator=( FunctionType f ){pf=f;} R operator()(const D& x) const { if (pf.failed()) throw UnsetPtrErr(); return pf(x); } virtual CheckedFunction* clone() const { return new CheckedFunction(*this); } Boolean equivalentTo(const CheckedFunction& rhs) const { return pf.failed() && rhs.pf.failed() || FunctionType(pf) == FunctionType(rhs.pf); } protected: Fallible< FunctionType > pf; }; template class CheckedIsoFunction : public CheckedFunction { public: CheckedIsoFunction( D(*f)(D) ):CheckedFunction(f){} }; template class CheckedBuiltInFunction : public virtual Functional, public EquivalentCategory< CheckedBuiltInFunction > { public: typedef R (*FunctionType)(D); CheckedBuiltInFunction ( FunctionType f ) : pf(f){ if(f==0)pf.invalidate(); } CheckedBuiltInFunction () : pf(){} void operator=( FunctionType f ){pf=f;} R operator()(const D& x) const { if (pf.failed()) throw UnsetPtrErr(); return pf(x); } virtual CheckedBuiltInFunction* clone() const { return new CheckedBuiltInFunction(*this); } Boolean equivalentTo(const CheckedBuiltInFunction& rhs) const { return pf.failed() && rhs.pf.failed() || FunctionType(pf) == FunctionType(rhs.pf); } protected: Fallible< FunctionType > pf; }; template class CheckedBuiltInIsoFunction : public CheckedBuiltInFunction { public: CheckedBuiltInIsoFunction( D(*f)(D) ):CheckedBuiltInFunction(f){} virtual CheckedBuiltInIsoFunction* clone() const { return new CheckedBuiltInIsoFunction(*this); } }; template inline IsoFunction function( D(*f)(const D&) ){ return IsoFunction(f); } template inline Function function( R(*f)(const D&) ){ return Function(f); } #endif