// Copyright 1996
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

// DblFcn.h

// This file contains tools for functions double ---> double

///////////////////////////////////////////////////////////////////////////////

#ifndef DBLFCN_H_
#define DBLFCN_H_

// Make a type definition DblFcnPtr to hold a pointer to a function of the form
//		double ---> double

typedef double (*DblFcnPtr) (double);


// Make a type definition DblFcnBase which can be used as the base class for
// defining parametrized functions of the form  double ---> double

// The default way to construct a DblFcnBase object will be with a DblFcnPtr
// This provides an automatic conversion from DblFcnPtr to DblFcnBase
// If no DblFcnPtr is provided then default function evaluation returns zero

// The operator  double operator() (double x) const  is virtual to permit
// override in derived classes

class DblFcnBase {
	DblFcnPtr	f;
	
public:
	// DblFcnBase Constructor
	DblFcnBase(DblFcnPtr F = 0) : f(F) { };
	
	// Direct set method
	void Set(const DblFcnPtr  F) { f = F; };
	
	// Direct get method
	void Get(DblFcnPtr& F) const { F = f; };
	
	// Default operator()
	virtual double operator() (double x) const {
		if (f == 0)
			return 0;		// return double 0 if f is null
		else
			return f(x);	// otherwise evaluate f at x
	};
};


// The template class DblFcn for standard override of the DblFcnBase class

// The parameter type DblFcnType should have an operator of the form
// 		double operator() (double x) const

// The data members of an object of type DblFcnType form the parameters of
// an associated "function object" which sends  double ---> double.

// If P is an object of type DblFcnType then DblFcn<DblFcnType>(P) defines
// a "function object" which acts as a function  double ---> double.  This
// function object depends on the data members or parameters hidden in the
// original object P.

// Since the internal object fcn is a reference to its initializer P, any
// changes to the data in P is immediately reflected in the action of the
// function fcn.

template <class DblFcnType> class DblFcn : public DblFcnBase {
	const DblFcnType& fcn;

public:
	// DblFcn Constructor
	
	// Note that unused function pointer f in the base class is default
	// initialized to the null pointer
	
	DblFcn(const DblFcnType& P) : fcn(P) { };
	
	// Standard override of the operator() definition
	double operator() (double x) const { return fcn(x); };
};

#endif // DBLFCN_H_
