Skip to content

Instantly share code, notes, and snippets.

@Dilink
Created July 5, 2021 22:02
Show Gist options
  • Save Dilink/788589486c6a4773290170d783260466 to your computer and use it in GitHub Desktop.
Save Dilink/788589486c6a4773290170d783260466 to your computer and use it in GitHub Desktop.
#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