#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

#if ((defined __GNUC__) && (__GNUC_MINOR__ > 91)) || (!defined __GNUC__)
namespace std {
#endif

template <class Arg1, class Arg2, class Result>
struct binary_function<Arg1, Arg2&, Result> {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
};      

// This is in fact a problem of older STL-versions shipped with g++
#if (defined __GNUC__) && (__GNUC_MINOR__ < 95) 
template <class S, class T, class A>
inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)) {
  return mem_fun1_ref_t<S,T,A>(f);
}
#endif

template <class A, class B, class C> 
class binder2nd<mem_fun1_ref_t<A,B,C> > 
  : public unary_function<typename mem_fun1_ref_t<A,B,C>::first_argument_type,
                          typename mem_fun1_ref_t<A,B,C>::result_type> {
protected:
  mem_fun1_ref_t<A,B,C> op;
  typename mem_fun1_ref_t<A,B,C>::second_argument_type value;
public:
  binder2nd(const mem_fun1_ref_t<A,B,C>& x,
            const typename mem_fun1_ref_t<A,B,C>::second_argument_type& y) 
      : op(x), value(y) {}
  typename mem_fun1_ref_t<A,B,C>::result_type
  operator()(typename mem_fun1_ref_t<A,B,C>::first_argument_type& x) const {
    return op(x, value); 
  }
};

/* // simplified version of the above //
template <class A, class B, class C> 
class binder2nd<mem_fun1_ref_t<A,B,C> > : public unary_function<B,A> {
protected:
  mem_fun1_ref_t<A,B,C> op;
  C value;
public:
  binder2nd(const mem_fun1_ref_t<A,B,C>& x, const C& y) : op(x), value(y) {}
  A operator()(B& x) const {
    return op(x, value); 
  }
};
*/
/*
template <class T, class A, class B, class C>
inline binder2nd<mem_fun1_ref_t<A,B,C> > bind2nd(const mem_fun1_ref_t<A,B,C> &op, const T& x) {
  typedef typename mem_fun1_ref_t<A,B,C>::second_argument_type arg2_type;
  return binder2nd<mem_fun1_ref_t<A,B,C> >(op, arg2_type(x));
}
*/


#if ((defined __GNUC__) && (__GNUC_MINOR__ > 91)) || (!defined __GNUC__)
} // namespace std
#endif

struct Point2D {
  double x, y;
  Point2D(double x, double y) : x(x), y(y) {}
  Point2D& sqrt() { double _x(x); x = x*x - y*y; y = 2*_x*y; return *this; }
  Point2D& translate(const Point2D &p) { x+= p.x; y+= p.y; return *this; }
  Point2D& translate(double u, double v) { x+= u; y+= v; return *this; }
};
ostream& operator<<(ostream &out, const Point2D &p) {
  return out << "(" << p.x << "," << p.y << ")";
}


int main() {
  vector<Point2D> vc;
  for (int i = 0; i < 10; ++i) vc.push_back(Point2D(i,i));
  for (int i = 0; i < 10; ++i) cout << vc[i] << ((i<9)?",":"\n");

  for_each(vc.begin(), vc.end(), 
    mem_fun_ref((Point2D&(Point2D::*)())(&Point2D::sqrt)));
  for (int i = 0; i < 10; ++i) cout << vc[i] << ((i<9)?",":"\n");

  for_each(vc.begin(), vc.end(), 
    bind2nd(mem_fun_ref((Point2D&(Point2D::*)(const Point2D&))(&Point2D::translate)),
            Point2D(-1,0)));
  for (int i = 0; i < 10; ++i) cout << vc[i] << ((i<9)?",":"\n");

  
  return 0;
}

