// placeholder.C
// --------------------------------------------------------------------
// Summer 2003: Algorithm Library Design, Juha K"arkk"ainen, 2003/05/27
// Homework 4: implement placeholders _1 and _2 to make this work
// Solution by Roman Dementiev, 2003/06/20

#include <iostream>
#include <algorithm>
#include <functional>
#include <iterator>

struct placeholder2_type
{
};

struct placeholder1_type
{
  template <class T>
  struct unary_greater
  {
    T obj;
    
    unary_greater(const T & arg): obj(arg) {}
      
    template <class E> 
    bool operator () (const E & arg) const
    {
        return (arg > obj);
    }
  };
  
  struct binary_greater
  {
    template <class A, class B>
    bool operator () (const A & a, const B & b) const
    {
      return a > b;
    }
  };
  
  template <class T>
  unary_greater<T> operator > (const T & obj) const
  {
    return unary_greater<T>(obj);
  }
  binary_greater operator > (const placeholder2_type &) const
  {
    return binary_greater();
  }
};

placeholder1_type _1;
placeholder2_type _2;


int main() {
  const int size = 6;
  int a[size] = { 2, 5, 1, 3, 6, 4 };
  float b[size] = { 4.0, 6.5, 4.5, 1.0, 5.0, 2.5 };
  std::ostream_iterator<int> int_out_iter(std::cout, " ");
  std::ostream_iterator<double> float_out_iter(std::cout, " ");

  std::cout << "Part (a): ";
  std::remove_copy_if(a, a+size, int_out_iter, _1 > 3);
  std::cout << "       (should be: 2 1 3)" << std::endl;

  std::cout << "Part (b): ";
  std::remove_copy_if(b, b+size, float_out_iter, _1 > 4.0);
  std::cout << "     (should be: 4 1 2.5)" << std::endl;

  std::cout << "Part (c): ";
  std::remove_copy_if(b, b+size, float_out_iter, _1 > 4);
  std::cout << "     (should be: 4 1 2.5)" << std::endl;

  std::cout << "Part (d): ";
  std::sort(a, a+size, _1 > _2);
  std::copy(a, a+size, int_out_iter);
  std::cout << " (should be: 6 5 4 3 2 1)" << std::endl;
}

