#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;
}