SNull.h 3.3 KB
Newer Older
gsell's avatar
gsell committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#ifndef OPAL_SNull_HH
#define OPAL_SNull_HH

// ------------------------------------------------------------------------
// $RCSfile: SNull.h,v $
// ------------------------------------------------------------------------
// $Revision: 1.1.1.1 $
// ------------------------------------------------------------------------
// Copyright: see Copyright.readme
// ------------------------------------------------------------------------
//
// Template class: SNull<T>
//
// ------------------------------------------------------------------------
//
// $Date: 2000/03/27 09:33:42 $
// $Author: Andreas Adelmann $
//
// ------------------------------------------------------------------------

#include "AbstractObjects/Expressions.h"
#include "Expressions/TFunction0.h"
#include "Utilities/DomainError.h"
#include "Utilities/OverflowError.h"
#include <cerrno>
#include <iostream>


namespace Expressions {

    // Class SNull
    // ----------------------------------------------------------------------
    /// A scalar expression without operands.
    //  This expression evaluates a scalar function withoud operands
    //  (e.g. a random generator) and returns the result.

    template <class T>
    class SNull: public Scalar<T> {

    public:

        /// Constructor.
        //  Use an operand-less scalar function.
        explicit SNull(const TFunction0<T> &function);

        SNull(const SNull<T> &);
        virtual ~SNull();

        /// Make clone.
        virtual Scalar<T> *clone() const;

        /// Evaluate.
        virtual T evaluate() const;

        /// Make expression.
        //  If the function is not a random generator, evaluate it and
        //  store the result as a constant.
        static Scalar<T> *make(const TFunction0<T> &function);

        /// Print expression.
        virtual void print(std::ostream &str, int precedence = 99) const;

    private:

        // Not implemented.
        SNull();
        void operator=(const SNull &);

        // The operation function.
        const TFunction0<T> &fun;
    };


    // Implementation
    // ------------------------------------------------------------------------

    template <class T> inline
    SNull<T>::SNull(const SNull<T> &rhs):
79
        Scalar<T>(rhs),
gsell's avatar
gsell committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
        fun(rhs.fun)
    {}


    template <class T> inline
    SNull<T>::SNull(const TFunction0<T> &function):
        fun(function)
    {}


    template <class T> inline
    SNull<T>::~SNull()
    {}


    template <class T> inline
    Scalar<T> *SNull<T>::clone() const {
        return new SNull<T>(*this);
    }


    template <class T> inline
    T SNull<T>::evaluate() const {
        errno = 0;
        T result = (*fun.function)();

        // Test for run-time evaluation errors.
        switch(errno) {

            case EDOM:
                throw DomainError("SNull:evaluate()");

            case ERANGE:
                // Ignore underflow.
                if(result == T(0)) return result;
                throw OverflowError("SNull:evaluate()");

            default:
                return result;
        }
    }


    template <class T> inline
    Scalar<T> *SNull<T>::make(const TFunction0<T> &fun) {
        return new SNull<T>(fun);
    }


    template <class T> inline
    void SNull<T>::print(std::ostream &stream, int) const {
        stream << fun.name << "()";
    }

}

#endif // OPAL_SNull_HH