Created
July 18, 2019 03:46
-
-
Save crcrpar/48940bec3e8d41c4bf0b1459a1085126 to your computer and use it in GitHub Desktop.
Curiously Recurring Template Pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Introduction to Curiously Recurring Template Pattern | |
| * | |
| * Ref: https://theolizer.com/cpp-school2/cpp-school2-19/ | |
| */ | |
| #include <iostream> | |
| #include <iomanip> | |
| #include <cstdint> | |
| #include <tuple> | |
| #define isDebug() 0 | |
| #if isDebug() | |
| // This is a big picture. | |
| template <class tDerived> | |
| class CrtpBase {}; | |
| class CrtpDerived : CrtpBase<CrtpDerived> {}; | |
| #endif | |
| template <class tDerived> | |
| struct CompareBase { | |
| // based on operator< | |
| bool operator>(tDerived const& iRhs) const { | |
| return (iRhs < static_cast<tDerived const&>(*this)); | |
| } | |
| bool operator==(tDerived const& iRhs) const { | |
| return !(static_cast<tDerived const&>(*this) < iRhs) && !(iRhs < static_cast<tDerived const&>(*this)); | |
| } | |
| bool operator !=(tDerived const& iRhs) const { | |
| return (static_cast<tDerived const &>(*this) < iRhs) || (iRhs < static_cast<const &>(*this)); | |
| } | |
| bool operator<=(tDerived const& iRhs) const { | |
| return !(iRhs < static_cast<tDerived const&>(*this)); | |
| } | |
| bool operator>=(tDerived const& iRhs) const { | |
| return !(static_cast<tDerived const&>(*this) < iRhs); | |
| } | |
| }; | |
| // struct Date { | |
| // uint16_t mYear; | |
| // uint8_t mMonth; | |
| // uint8_t mDay; | |
| // | |
| // Date(uint16_t iYear, uint8_t iMonth, uint8_t iDay) | |
| // : mYear(iYear), mMonth(iMonth), mDay(iDay) {} | |
| // | |
| // bool operator<(Date const& iRhs) const { | |
| // return std::tie(mYear, mMonth, mDay) < std::tie(iRhs.mYear, iRhs.mMonth, iRhs.mDay); | |
| // } | |
| // | |
| // // Deduce from operator< | |
| // bool operator>(Date const& iRhs) const { return iRhs < *this; } | |
| // bool operator==(Date const& iRhs) const { return !(*this < iRhs) && !(iRhs < *this); } | |
| // bool operator!=(Date const& iRhs) const { return (*this < iRhs) || (iRhs < *this); } | |
| // bool operator<=(Date const& iRhs) const { return !(iRhs < *this); } | |
| // bool operator>=(Date const& iRhs) const { return !(*this < iRhs); } | |
| // }; | |
| struct Date : public CompareBase<Date> { | |
| uint16_t mYear; | |
| uint8_t mMonth; | |
| uint8_t mDay; | |
| Date(uint16_t iYear, uint8_t iMonth, uint8_t iDay) | |
| : mYear(iYear), mMonth(iMonth), mDay(iDay) {} | |
| bool operator<(Date const& iRhs) const { | |
| return std::tie(mYear, mMonth, mDay) < std::tie(iRhs.mYear, iRhs.mMonth, iRhs.mDay); | |
| } | |
| }; | |
| struct SizeString : public std::string, public CompareBase<SizeString> { | |
| using std::string::string; | |
| bool operator<(SizeString const& iRhs) const { | |
| return size() < iRhs.size(); | |
| } | |
| }; | |
| // After the above definitions, we wanted to define order btwn strings by their length. | |
| // struct SizeString : public std::string { | |
| // using std::string::string; | |
| // | |
| // bool operator<(SizeString const& iRhs) const { | |
| // return size() < iRhs.size(); | |
| // } | |
| /* This repetitive definition is tedious and easy to cause mistakes. | |
| * Here, we can utilize CRTP. | |
| * bool operator>(SizeString const& iRhs) const { return iRhs < *this; } | |
| * bool operator==(SizeString const& iRhs) const { return !(*this < iRhs) && !(iRhs < *this); } | |
| * bool operator!=(SizeString const& iRhs) const { return (*this < iRhs) || (iRhs < *this); } | |
| * bool operator<=(SizeString const& iRhs) const { return !(*this < iRhs); } | |
| * bool operator>=(SizeString const& iRhs) const { return !(iRhs < *this); } | |
| */ | |
| // }; | |
| int main() { | |
| Date aToday(2019, 7, 18); | |
| Date aTomorrow(2019, 7, 19); | |
| std::cout << std::boolalpha; | |
| std::cout << "aToday < aTomorrow = " << (aToday < aTomorrow) << std::endl; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment