Created
July 5, 2021 22:02
-
-
Save Dilink/788589486c6a4773290170d783260466 to your computer and use it in GitHub Desktop.
This file contains 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
#include <iostream> | |
template <typename T> | |
struct CRTP | |
{ | |
inline T& underlying() { return static_cast<T&>(*this); } | |
inline const T& underlying() const { return static_cast<const T&>(*this); } | |
}; | |
using uint16 = unsigned short int; | |
class RecursionScopeMarker | |
{ | |
private: | |
uint16& m_Counter; | |
public: | |
RecursionScopeMarker(uint16& counter) : m_Counter(counter) { ++m_Counter; } | |
~RecursionScopeMarker() { --m_Counter; } | |
}; | |
#define _CONCAT(a, b) a##b | |
#define CONCAT(a, b) _CONCAT(a, b) | |
#ifdef _DEBUG | |
#define checkNoRecursion() static uint16 CONCAT(recursionCounter, __LINE__) = 0; \ | |
if (CONCAT(recursionCounter, __LINE__) != 0) { __debugbreak(); } \ | |
const RecursionScopeMarker CONCAT(ScopeMarker, __LINE__)(CONCAT(recursionCounter, __LINE__)) | |
#else | |
#define checkNoRecursion() | |
#endif // _DEBUG | |
#pragma warning(push) | |
#pragma warning(disable: 4717) | |
template <typename Derived> | |
struct Base : CRTP<Derived> | |
{ | |
void implementation() { | |
checkNoRecursion(); // Implementation should be defined | |
this->underlying().implementation(); | |
} | |
}; | |
#pragma warning(pop) | |
struct Derived1 : Base<Derived1> { | |
void implementation() { | |
std::cout << "Implementation Derived1" << std::endl; | |
} | |
}; | |
struct Derived2 : Base<Derived2> { | |
void implementation() { | |
std::cout << "Implementation Derived2" << std::endl; | |
} | |
}; | |
struct Derived3 : Base<Derived3> {}; | |
int main() | |
{ | |
std::cout << std::endl; | |
Derived1 d1; | |
d1.implementation(); | |
Derived2 d2; | |
d2.implementation(); | |
Derived3 d3; | |
d3.implementation(); | |
std::cout << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment