#include <iostream>
// Guideline P1 is about expressing ideas directly in code. One part of that is // about using user defined types that express an idea better than say an int. // This file takes the Date/Month example in P1 and expands upon it.
// Neutral 1 : Despite wrapping the unsigned int it is no slower.
struct CalendarType { // Neutral 2 : The user does not know if the value is 0 based or 1 based.
unsigned int value;
// Cost 1 : Either the user has to use say month.value or we have to write boiler plate code for required methods.
// Mitigation 1 : C++ 20 boiler plate for comparison operators is a couple of one liners.
bool operator==(const CalendarType &other) const = default;
std::strong_ordering operator<=>(const CalendarType &other) const = default;
};// Cost 2 : We have a bit of boiler plate code to write. // Mitigation 2 : We've put the common code into a base class.
struct Year : CalendarType { explicit Year(int year) : CalendarType(year) {} };
struct Month : public CalendarType { explicit Month(int month) : CalendarType(month) {} };
struct Day : public CalendarType { explicit Day(int day) : CalendarType(day) {} };
class Date { public: Date(Year year, Month month, Day day) : m_year(year), m_month(month), m_day(day) { }
Year year() const
{
return m_year;
}
Month month() const
{
return m_month;
}
Day day() const
{
return m_day;
}
private:
// Cost 3 : To fully understand, the reader needs to look at how Year, Month and Day are implemented. Year m_year;
Month m_month;
Day m_day;
};int main() { // Cost 2 :
Date date1 {Year(1970), Month(4), Day(7)}; // Benefit 1 : It's clear to the reader what each argument is.
Date date2 {Year(1983), Month(1), Day(12)};
// Date date3 {7, 4, 1979}; // Benefit 2 : Code writer can't get them in the wrong order
// (courtesy of explicit this wont compile).
// (Yes, I've glossed over leap year edge cases)
bool earlierInTheYear = date2.month() < date1.month() ||
date2.month() == date1.month() && date2.day() < date1.day();
std::cout << "1983-01-12 " << (earlierInTheYear ? "is" : "is not")
<< " earlier in the year than 1970-04-07" << std::endl;
}