#include <iostream>
#include <iomanip>

class Date {
public:

  enum fmt{hu, us, de,N};
  

  Date(int y,int m, int d):year(y), month(m), day(d) {};
  int get_day() const { return day; }
  int get_month() const { return month; }
  int get_year() const { return year;}

  friend struct Manip;
  friend std::ostream& operator<<(std::ostream& os,const Date&);
  friend std::ostream& sepchar(std::ostream& os, char ch);
  friend std::ostream& hu(std::ostream& os);
  friend std::ostream& de(std::ostream& os);
  friend std::ostream& us(std::ostream& os);
private:
  int year;
  int month;
  int day;
  static char sch;
  static int (Date::*print1st)() const;
  static int (Date::*print2nd)() const;
  static int (Date::*print3rd)() const;
  void print(std::ostream& os) const;
  
};

char Date::sch=' ';
int (Date::*Date::print1st)() const = &Date::get_year;
int (Date::*Date::print2nd)() const = &Date::get_month;
int (Date::*Date::print3rd)() const = &Date::get_day;

struct Manip {
  std::ostream& (*f)(std::ostream&, char ch); 
  char sep;
  Manip(std::ostream& (*ff)(std::ostream&, char), char c): f(ff), sep(c) {}
  ~Manip() {Date::sch=' ';}
};

std::ostream& operator<<(std::ostream& os, const Manip& m) {
  return m.f(os, m.sep);
}

std::ostream& sepchar(std::ostream& os, char ch) {
    Date::sch=ch;
    return os;
}

inline Manip setsc(char ch) {
  return Manip(sepchar,ch);
}

std::ostream& hu(std::ostream& os) {  
  for(int i=0;i<Date::N;++i)
    os.iword(i)=false;

  os.iword(Date::hu) = true;
  Date::print1st = &Date::get_year;
  Date::print2nd = &Date::get_month;
  Date::print3rd = &Date::get_day;
  return os;
}

std::ostream& us(std::ostream& os) {  
  for(int i=0;i<Date::N;++i)
    os.iword(i)=false;

  os.iword(Date::us) = true;
  Date::print1st = &Date::get_month;
  Date::print2nd = &Date::get_day;
  Date::print3rd = &Date::get_year;
  return os;
}

std::ostream& de(std::ostream& os) {  
  for(int i=0;i<Date::N;++i)
    os.iword(i)=false;

  os.iword(Date::de) = true;
  Date::print1st = &Date::get_day;
  Date::print2nd = &Date::get_month;
  Date::print3rd = &Date::get_year;
  return os;
}

void Date::print(std::ostream& os) const {
  os << (this->*print1st)() << Date::sch 
     << (this->*print2nd)() << Date::sch
     << (this->*print3rd)() << Date::sch;
}

std::ostream& operator<<(std::ostream& os, const Date& d) {
  d.print(os);
  return os;
}

int main() {
  const Date today(2000,4,14);

  std::cout << today << std::endl;
  std::cout << us;
  std::cout << setsc('.')<< today << std::endl;
  std::cout << de;
  std::cout << today << std::endl;
  return 0;
}