#include <iostream>
#include<string>
#include <cctype>
#include <stdexcept>
struct day_type
{
enum weekday { SUN, MON, TUE, WED, THU, FRI, SAT };
day_type(weekday day) : _day(day) {}
day_type(std::string day);
day_type prev() const { return dec(_day); }
day_type next() const { return inc(_day); }
day_type operator+(unsigned n_days) { return weekday((_day + n_days) % 7); }
day_type operator-(unsigned n_days) { return *this; /* I leave this to you! */ }
operator std::string() const;
private:
weekday _day;
static weekday dec(weekday d) { return d == 0 ? weekday(6) : weekday(d-1); }
static weekday inc(weekday d) { return weekday((d + 1) % 7);}
};
std::string to_string(day_type::weekday day)
{
static const char* days [] =
{
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
return days[day];
}
void to_lower(std::string& str)
{
for (auto&ch : str)
ch = std::tolower(ch);
}
day_type::operator std::string() const
{
return to_string(_day);
}
day_type::day_type(std::string day)
{
static const std::string days [] =
{
"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"
};
unsigned matches = 0;
unsigned match_index;
to_lower(day);
for (unsigned index=0; index != 7 && matches <= 1; ++index)
{
if (days[index].find(day) != std::string::npos)
{
match_index = index;
++matches;
}
}
if (matches != 1)
throw std::invalid_argument("\"" + day + "\" is not a valid day");
_day = weekday(match_index);
}
int main()
{
const char* day_prompt = "Enter a day of the week (quit to stop):\n";
std::string today;
while (std::cout << day_prompt && std::cin >> today && today != "quit")
{
try
{
day_type day(today);
std::cout << "Day is " << std::string(day) << ".\n";
std::cout << "Previous day was " << std::string(day.prev()) << ".\n";
std::cout << "Next day is " << std::string(day.next()) << ".\n";
std::cout << "How many days would you like to add?\n";
unsigned to_add;
std::cin >> to_add;
std::cout << "In " << to_add << " days it will be " ;
std::cout << std::string(day + to_add) << ".\n\n";
}
catch (std::exception & ex)
{
std::cout << "ERROR: " << ex.what() << "\n\n";
}
}
}