#include<cmath>
#include<math.h>

#include<iostream>


class Sin {
  
public:
  enum arg {radian,degree,grad};
  
  Sin(arg s = radian):_state(s) {};

  void set_radians() { _state=radian;}
  void set_degrees() {_state=degree;}
  void set_grads()   {_state=grad;}

  double operator()(double x) {return sin(conv(x));}

private:
  arg _state;

  double conv(double x) {
    switch (_state) {
    case radian: return x;
    case degree : return x*(M_PI/180.0);
    case grad   : return x*(M_PI/200.0);
    }
  }
  
};

class BetterSin {  
public:
  enum arg {radian,degree,grad};
  
  void set_radians() { _conv=&BetterSin::to_radians;}
  void set_degrees() { _conv=&BetterSin::to_degrees;}
  void set_grads()   { _conv=&BetterSin::to_grads;}

  double operator()(double x) {return sin( (this->*_conv)(x) );}

  BetterSin(arg s = radian) {
    switch (s) {
    case radian: set_radians();break;
    case degree : set_degrees();break;
    case grad   : set_grads();break;
    }
  }


private:

  double (BetterSin::* _conv)(double);

  double to_radians(double x) {return x;};
  double to_degrees(double x) {return x*(M_PI/180.0);};
  double to_grads(double x) {return x*(M_PI/200.0);};
  
};


main() {
  BetterSin s_r;
  BetterSin s_d(BetterSin::degree);

  std::cout<<s_r(M_PI)<<std::endl;
  std::cout<<s_d(180.0)<<std::endl;

  s_d.set_grads();

  std::cout<<s_d(200.0)<<std::endl;

}