2009年1月10日 星期六

二元仿函式(Binary Functors(Function Object))配接器(Adapters)練習

二元仿函式(Binary Functors(Function Object))配接器(Adapters)練習
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <ctime>
#include <iterator>
using namespace std;
class test {
public:
  int m_x, m_y;
  typedef test this_type;
  inline test(const int &x = 0, const int &y = 0): m_x(x), m_y(y) {}
  inline test(const this_type &d): m_x(d.m_x), m_y(d.m_y) {}
  inline this_type &operator = (const this_type &d) {
    m_x = d.m_x;
    m_y = d.m_y;
    return *this;
  }
  inline this_type &set(const int &x = 0, const int &y = 0) {
    m_x = x;
    m_y = y;
    return *this;
  }
};
inline ostream &operator<<(ostream &os, const test &d) {
  ios_base::fmtflags ff = os.flags();
  os << "(" << setw(3) << d.m_x << "," << setw(3) << d.m_y << ")";
  os.flags(ff);
  return os;
}
class testNulOp {
public:
  static int a;
  int m_sa;
  enum Action {_increase, _random, _value} action;
  inline testNulOp(const Action &a = _increase): m_sa(0), action(a) {}
  inline testNulOp(const int &sa, const Action &a = _value): m_sa(sa), action(a) {}
  inline test operator()(void) const {
    switch(action) {
    case _increase:
      return test(a++, ++a);
      break;
    case _random :
      return test(rand() % 0xff, rand() % 0xff);
      break;
    case _value :
      return test(m_sa, m_sa);
      break;
    default :
      return test(0, 0);
      break;
    }
  }
};
int testNulOp::a = 0;
class testUniOp: unary_function<test, test> {
public:
  int m_sa;
  enum Action {_reset, _set} action;
  inline testUniOp(const Action &a = _reset): m_sa(0), action(a) {}
  inline testUniOp(const int &sa, const Action &a = _set): m_sa(sa), action(a) {}
  inline test &operator()(test &R) const {
    switch(action) {
    case _reset:
      return R.set(0, 0);
      break;
    case _set:
      return R.set(m_sa, m_sa);
      break;
    default :
      return R;
      break;
    }
  }
};
class testBinOp: public binary_function<test, test, bool> {
public:
  enum Action {_lessX, _lessY, _equal} action;
  inline testBinOp(const Action &a = _lessX): action(a) {
  }
  inline bool operator()(const test &L, const test &R) const {
    switch(action) {
    case _lessX:
      if(L.m_x != R.m_x) {
        return L.m_x < R.m_x;
      } else {
        return L.m_y < R.m_y;
      }
      break;
    case _lessY:
      if(L.m_y != R.m_y) {
        return L.m_y < R.m_y;
      } else {
        return L.m_x < R.m_x;
      }
      break;
    case _equal:
      return (L.m_x == R.m_x) && (L.m_y == R.m_y);
      break;
    default :
      return false;
      break;
    }
  }
};
int main(int argc, char *argv[]) {
  vector<test> myvector(9);
  typedef vector<test>::const_iterator vtci;
  srand((unsigned int)time(0) & 0xffULL);
  generate(myvector.begin(), myvector.end(), testNulOp(testNulOp::_increase));
  generate_n(back_inserter(myvector), 10, testNulOp(testNulOp::_random));
  generate_n(back_inserter(myvector), 10, testNulOp(30));
  copy(myvector.begin(), myvector.end(), ostream_iterator<test>(cout, "\n"));
  cout << "--------------------------------------------------" << endl;
  sort(myvector.begin(), myvector.end(), testBinOp(testBinOp::_lessY));
  copy(myvector.begin(), myvector.end(), ostream_iterator<test>(cout, "\n"));
  vtci iit = find_if(myvector.begin(), myvector.end(),
                     bind2nd(testBinOp(testBinOp::_equal), test(30, 30)));
  cout << endl << *iit << endl;
  cout << "--------------------------------------------------" << endl;
  for_each(myvector.begin(), myvector.end(), testUniOp(testUniOp::_reset));
  copy(myvector.begin(), myvector.end(), ostream_iterator<test>(cout, "\n"));
  system("pause");
  return EXIT_SUCCESS;
}

沒有留言:

張貼留言