#include<iostream>
#include<functional>
#include<ext/functional>
#include<cmath>
#include<boost/function.hpp>
using namespace boost;


template<typename F,typename G> class compose_f_gxy_t {
  typedef typename F::result_type result_type;
  typedef typename G::first_argument_type  first_argument_type;
  typedef typename G::second_argument_type  second_argument_type;

  F _f;
  G _g;

public:
  compose_f_gxy_t(F f,G g):_f(f),_g(g) {};

  result_type operator()(first_argument_type x,
			 second_argument_type y) {
    return _f(_g(x,y));
  }
  
};

template<typename F,typename G> 
compose_f_gxy_t<F,G>
compose_f_gxy(F f,G g) {return  compose_f_gxy_t<F,G>(f,g);};


class Cov:public std::binary_function<double,double,double> {
  const double _ax,_ay,_axy;
public: 
  Cov(double ax,double ay,double axy):_ax(ax),_ay(ay),_axy(axy) {};
  double operator()(double x,double y)const {return _ax*x*x+_ay*y*y+_axy*x*y;}
};



main() {

  Cov f(1.0,2.0,2.0);
  
  std::cout<<f(1.0,1.0)<<"\n";
  std::cout<<f(1.0,2.0)<<"\n";


  boost::function<double (double,double)>  fc;
  fc=compose_f_gxy(
			   __gnu_cxx::compose1(std::ptr_fun(exp),
					 std::negate<double>()),
			   f);

  std::cout<<fc(1.0,1.0)<<"\n";
}
