#ifndef FNOBJT_H
#define FNOBJT_H

#include <fnobj.h>

/*
  These objects hide their type when using with a 
  reference to their base class.

  Different objects with the same funcional object signature
  can be grouped together.
*/


/*!
  \brief Pass functional objects around with A0 ()() signature.
*/
template< class T, class A0 >
class fnobj0T : public fnobj0<A0>
{
public:

  T obj;

  fnobj0T(T obj_) : obj(obj_) {} 

  A0 operator () () { obj(); }
};

/*!
  \brief Pass functional objects around with A0 ()() const signature.
*/
template< class T, class A0 >
class fnobj0constT : public fnobj0const<A0>
{
public:

  T obj;

  fnobj0constT(T obj_) : obj(obj_) {} 

  A0 operator () () const { obj(); }
};


/*!
  \brief Pass functional objects around with A0 ()(A1) signature.
*/
template< class T, class A0, class A1 >
class fnobj1T : public fnobj1<A0,A1>
{
public:

  T obj;

  fnobj1T(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1) { obj(a1); }
};

/*!
  \brief Pass functional objects around with A0 ()(A1) const signature.
*/
template< class T, class A0, class A1 >
class fnobj1constT : public fnobj1const<A0,A1>
{
public:

  T obj;

  fnobj1constT(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1) const { obj(a1); }
};


/*!
  \brief Pass functional objects around with A0 ()(A1,A2) signature.
*/
template< class T, class A0, class A1, class A2 >
class fnobj2T : public fnobj2<A0,A1,A2>
{
public:

  T obj;

  fnobj2T(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1, A2 a2) { obj(a1,a2); }
};

/*!
  \brief Pass functional objects around with A0 ()(A1,A2) signature.
*/
template< class T, class A0, class A1, class A2 >
class fnobj2constT : public fnobj2const<A0,A1,A2>
{
public:

  T obj;

  fnobj2constT(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1, A2 a2) const { obj(a1,a2); }
};


/*!
  \brief Pass functional objects around with A0 ()(A1,A2,A3) signature.
*/
template< class T, class A0, class A1, class A2, class A3 >
class fnobj3T : public fnobj3<A0,A1,A2,A3>
{
public:

  T obj;

  fnobj3T(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1, A2 a2, A3 a3) { obj(a1,a2,a3); }
};

/*!
  \brief Pass functional objects around with A0 ()(A1,A2,A3) signature.
*/
template< class T, class A0, class A1, class A2, class A3 >
class fnobj3constT : public fnobj3const<A0,A1,A2,A3>
{
public:

  T obj;

  fnobj3constT(T obj_) : obj(obj_) {} 

  A0 operator () (A1 a1, A2 a2, A3 a3) const { obj(a1,a2,a3); }
};



#endif



