#ifndef FUNCTION_H_
#define FUNCTION_H_

#include <string>
#include <vector>

class SArray;
class Index;

/**
 * An abstract base class for functions.
 *
 * Function objects contain only constant data members and all member
 * functions are constant. Hence only one object needs to be
 * instantiated for each subclass.
 *
 * @see FuncTab
 * @short Function
 */
class Function
{
  const std::string _name;
  const unsigned int _npar;
 public:
  /**
   * Constructor.
   * @param name name of the function as used in the BUGS language
   * @param npar number of parameters. If npar == 0 then the function
   * takes a variable number of parameters.
   */
  Function (std::string const &name, unsigned int npar);
  virtual ~ Function ();
  /**
   * Returns the  BUGS language name of the function
   */
  std::string const &name () const;
  /**
   * Evaluates the function. This function assumes that checParameterkDim and
   * checkParameterValue return true.
   *
   * @param value SArray which is modified to contain the result of
   * the evaluation 
   * @param args Vector of arguments
   */
  virtual void
    evaluate (SArray & value,
	      std::vector <SArray const *> const &args) const = 0;
  /**
   * Checks that parameter vector is of correct length
   */
  bool 
    checkParameterLength (std::vector <SArray const *> const &args) const;
  /**
   * Checks whether dimensions of the arguments are correct. This
   * function assumes that checkParameterLength returns true.
   */
  virtual bool
    checkParameterDim (std::vector <SArray const *> const &args) const = 0;
  /**
   * Checks whether the parameter values lie in the domain of the
   * function.  This assumes that the function checkparameterDim
   * returns true.
   *
   * Since many functions do not need to check their parameter
   * values, a default method is provided which always returns
   * true.
   */
  virtual bool
    checkParameterValue (std::vector <SArray const *> const &args) const;
  /**
   * Calculates what the dimension of the return value should be,
   * based on the arguments. This function assumes that
   * checkParameterDim is correct.
   */
  virtual Index dim (std::vector <SArray const *> const &args) const = 0;
  /**
   * Returns true if the function returns integer values. The default
   * implementation returns false, so any function that can return
   * integer values will need to overload this.
   *
   * @see SArray##isDiscreteValued
   */
  virtual bool isDiscreteValued(std::vector<SArray const *> const &args) const;
};

/** 
 * Returns true if all the elements of the given vector are
 * discrete-valued.  This is a helper to allow simple implementation
 * of Function##isDiscreteValued for some subclasses of Function
 */
bool allDiscrete(std::vector<SArray const *> const &args);

#endif /* FUNCTION_H_ */


syntax highlighted by Code2HTML, v. 0.9.1