//  Call Wrappers


template <class T>
class matrix
{
public:
       matrix( int i, int j );
       matrix( const matrix &other);
       ~matrix();
    matrix& operator=( const matrix &other);

    int rows() const { return x; }
    int cols() const { return y; }

          T& at( int i, int j)       throw(indexError);
    const T& at( int i, int j) const throw(indexError);
          T& operator()( int i, int j);
    const T& operator()( int i, int j) const;
private:
    int  x;
    int  y;
    T   *v;
    void copy( const matrix &other);
    void check( int i, int j) const throw(indexError);
};


//  Functor: class with function call operator 
//  Function pointers are callable types too.
//
//  Tr1 introduces 4 new class templates to create Functors
//


#include <functional>


reference_wrapper
function
mem_fn
bind

ref
cref
result_of





//  Terminology

Callable_type:

- pointer to function
- pointer to member function
- pointer to member data
- objects left to a function call

Examples:

double (*fptr)(double);         // pointer to function

int    (date::*getter)() const; // pointer to member function

int     date::*field;           // pointer to member data

class C                         // function call operator
{
public:
    void operator()(int i);
};


fptr = sin;
getter = &date::get_year;
field  = &date::year;
C c;

fptr(0.5)  <==>  (*fptr)(0.5)
(obj.*getter)()
((*ptr).*getter)() <==>  (ptr->*getter)()
c.operator() <==> c()



#include <iostream>
#include <math.h>
using std::cout;

class wrapper // simple call wrapper type
{
  typedef float(*fp)(float);
public:
  wrapper(fp ptr) : fptr(ptr) {}
  float operator()(float arg) // call operation; forwards to target object
  {
    return fptr(arg);
  }
private:
  fp fptr;              // target object
};

int main() // demonstrate use of call wrapper
{
  wrapper wrap(cosf);   // call wrapper
  cout << "cosf(1.0) is " << cosf(1.0) << '\n';
  cout << "wrap(1.0) is " << wrap(1.0) << '\n';
  return 0;
};

// A call wrapper can be copy constructed


//  INVOKE

INVOKE( fn, t1, t2, ... , tN)

    (t1.*fn)(t2, ... , tN)     // pointer to member function 
    ((*t1).*fn)(t2, ... , tN)  // pointer to member function
    t1.*fn                  // pointer to member data
    (*t1).*fn               // pointer to member data
    fn( t1, t2, ... , tN)   // otherwise


INVOKE_R( fn, t1, t2, ... , tN, Ret)    // INVOKE() converts to Ret



struct base
{
    void f();
    int  g(double);
    int h(double, double);
};

struct derived : base
{
};

base    b;
derived d;
base&   br = d;


INVOKE( &base::f, b)                (b.*f)()
INVOKE( &base::g, d, 1.0)           (d.*f)(1.0)
INVOKE( &base::h, br, 1.0, 2.0)     (br.*f)(1.0, 2.0)


derived *dp = new derived;
base    *bp = dp;
shared_ptr<base> sp(bp);


INVOKE( &base::f, bp)               ((*bp).*f)()
INVOKE( &base::g, dp, 1.0)          ((*dp).*f)(1.0)
INVOKE( &base::h, sp, 1.0, 2.0)     ((*sp).*f)(1.0, 2.0)


void func(base&);
struct fun_obj
{
    void operator()() const;
    bool operator()(int) const;
};
fun_obj obj;


INVOKE( func, d)        func(d)
INVOKE( obj)            obj()
INVOKE( obj, 3)         obj(3)




#include <functional>
#include <math.h>
#include <iostream>
#include <typeinfo>
using std::tr1::result_of;
using std::ostream;
using std::cout;

class C
{ // sample class
public:
  C(int i0) : i(i0) {}
  long get() const { return i; }
  int i;
  void operator()(int ii) { i = ii; }
  typedef void result_type;
};

template <class Fty, class Arg>
void show_return(Fty fun, Arg arg)
{ // show return type of fun(arg)
  typedef typename result_of<Fty(Arg)>::type ret;
  cout << "Return type of " << typeid(Fty).name()
    << " when called with " << typeid(Arg).name()
    << " is " << typeid(ret).name() << '\n';
}

int main()
{ // demonstrate class template result_of
  C c(1);
  C *cp = &c;
  const C *ccp = &c;
  show_return(cosf, 1.0);       // cosf(float) returns float
  show_return(&C::get, cp);     // C::get() returns long
  show_return(&C::i, ccp);      // C::i has type const int
  show_return(c, 3);            // C() returns void
  return 0;
}



//  mem_fn

template <class Ret, class T>
XXXX  mem_fn(Ret T::*pm);


returns a simple call wrapper cw, where

cw(a1, a2, ... , aN)   <==>    INVOKE(pm, a1, a2, ... , aN)

XXXX : std::unary_function<T*, Ret>   -->  typedef Ret result_type
                                      -->  typedef T*  argument_type


#include <functional>
#include <memory>
#include <iostream>
using std::tr1::mem_fn; using std::tr1::shared_ptr;
using std::cout;

class C
{ // simple class with member function
public:
  C(int i0 = 0) : i(i0) {}
  void show() const
  { // show contents
    cout << i << '\n';
  }
private:
  int i;
};

template <class Fty, class Ty>
void apply(Fty fn, Ty obj)
{ // call a function object with one argument
  fn(obj);
}

int main()
{ // demonstrate simple use of mem_fn
  C c0(0);
  C *cp = new C(1);
  shared_ptr<C> sp(new C(2));
  void (C::*mptr)() const = &C::show;

  apply(mem_fn(mptr), c0);  // equivalent to (c0.*mptr)()
  apply(mem_fn(mptr), cp);  // equivalent to (cp->*mptr)()
  apply(mem_fn(mptr), sp);  // equivalent to ((*sp).*mptr)()

  delete cp;
  return 0;
}


#include <functional>
#include <iostream>
using std::tr1::mem_fn;
using std::cout;

class C
{ // simple class with member functions
public:
  C(int i0 = 0) : i(i0) {}
  void show() const
  { // show contents
    cout << "in show: " << i << '\n';
  }
  void one_arg(int j) const
  { // member function taking one argument
    cout << "in one_arg: " << i
         << ", " << j << '\n';
  }
  void two_args(int j, int k) const
  { // member function taking two arguments
    cout << "in two_args: " << i
         << ", " << j << ", " << k << '\n';
  }
private:
  int i;
};

int main()
{
  C c(1);
  int two = 2;
  int three = 3;
  mem_fn(&C::show)(c);                // c.show();
  mem_fn(&C::one_arg)(c, two);        // c.one_arg(two);
  mem_fn(&C::two_args)(c, two, three);// c.two_args(two, three);
  return 0;
}


//  reference_wrapper

//  creates objects acting like referencies 
//  but could be copied


#include <functional>
using std::tr1::reference_wrapper;

class ref
{ // simple class containing reference
public:
  ref(int& i) : member(i) {}
private:
  int& member;
};

class refwrap
{ // simple class containing reference_wrapper
public:
  refwrap(int& i) : member(i) {}
private:
  reference_wrapper<int> member;
};

void f()
{ // demonstrate copying
  int i, j;
  ref r0(i);
  ref r1(j);
  r1 = r0;      // error: ref can't be copied

  refwrap rw0(i);
  refwrap rw1(j);
  rw1 = rw0;    // okay: refwrap can be copied
}



#include <functional>
#include <iostream>
using std::tr1::reference_wrapper;
using std::cout;

int main()
{ // demonstrate basic use of reference_wrapper
  int Stuhldreher = 3;
  reference_wrapper<int> rw(Stuhldreher);
  cout << rw << '\n';           // displays value of Stuhldreher
  Stuhldreher = 4;
  cout << rw << '\n';           // displays new value of Stuhldreher
  rw.get() = 5;                 // changes value of Stuhldreher
  cout << Stuhldreher << '\n';  // displays new value
  return 0;
}



#include <functional>
#include <iostream>
using std::tr1::reference_wrapper;
using std::tr1::ref;
using std::tr1::cref;
using std::cout;

void show(int& i)
{ // show value referred to by reference to int
  cout << "int&: " << i << '\n';
}

void show(const int& i)
{ // show value referred to by reference to const int
  cout << "const int&: " << i << '\n';
}

int main()
{ // demonstrate use of ref and cref
  int Miller = 3;
  show(ref(Miller));    // calls show(int&);
  reference_wrapper<int> rw0(Miller);
  show(ref(rw0));       // calls show(int&);
  show(cref(Miller));   // calls show(const int&);
  reference_wrapper<const int> rw1(Miller);
  show(cref(rw1));      // calls show(const int&);
  return 0;
}



#include <functional>
#include <iostream>
using std::tr1::reference_wrapper;
using std::cout;

struct base
{ // base class
  virtual void show() const
  { // show name of base class
    cout << "base\n";
  }
};

struct derived0 : base
{ // one derived class
  void show() const
  { // show name of derived class
    cout << "derived0\n";
  }
};

struct derived1 : base
{ // another derived class
  void show() const
  { // show name of derived class
    cout << "derived1\n";
  }
};

int main()
{ // demonstrate reference_wrapper's support for polymorphism
  derived0 Crowley;
  derived1 Layden;
  reference_wrapper<base> rw0(Crowley);
  rw0.get().show();         // calls derived0::show
  reference_wrapper<base> rw1(Layden);
  rw1.get().show();         // calls derived1::show
  return 0;
}


#include <functional>
#include <iostream>
using std::tr1::reference_wrapper;
using std::tr1::cref;
using std::cout;

void hello()
{ // simple function
  cout << "Hello, world\n";
}

void goodbye()
{ // another simple function
  cout << "Goodbye, cruel world\n";
}

int main()
{ // demonstrate invocation of reference_wrapper object
  typedef void (*const fun)();
  reference_wrapper<fun> rw(&hello);
  rw();         // calls hello
  rw = cref(&goodbye);
  rw();         // calls goodbye
  return 0;
}



//  function