#ifndef DATEH #define DATEH #include using namespace std; class date { static const int length[]; int year; //must construct data members in this order int month; //date::january to date::december inclusive int day; //1 to length[month] inclusive public: enum month_t { //indices into the length array january = 1, february, march, april, may, june, july, august, september, october, november, december }; //Exceptions thrown by the constructor of class date: class bad_month { const int month; public: bad_month(int initial_month): month(initial_month) {} virtual ~bad_month() {} virtual void print(ostream& ost) const {ost << "bad month " << month;} }; class bad_month_and_day: public bad_month { const int day; void print(ostream& ost) const { bad_month::print(ost); ost << ", day " << day; } public: bad_month_and_day(int initial_month, int initial_day) : bad_month(initial_month), day(initial_day) {} }; //Exceptions thrown by the 'crement operators functions of class date: class flow { virtual void print(ostream&) const = 0; public: virtual ~flow() {} friend ostream& operator<<(ostream& ost, const flow& f) { f.print(ost); return ost; } }; class overflow: public flow { void print(ostream& ost) const { ost << "can't go beyond December 31, " << INT_MAX; } }; class underflow: public flow { void print(ostream& ost) const { ost << "can't go before January 1, " << INT_MIN; } }; date(int initial_month, int initial_day, int initial_year) throw (bad_month); date& operator++() throw (overflow); date& operator--() throw (underflow); const date operator++(int) throw (overflow) { const date old = *this; ++*this; return old; } const date operator--(int) throw (underflow) { const date old = *this; --*this; return old; } friend ostream& operator<<(ostream& ost, const date& d) { return ost << d.month << "/" << d.day << "/" << d.year; } }; inline ostream& operator<<(ostream& ost, const date::bad_month& bm) { bm.print(ost); return ost; } #endif