Created
May 7, 2013 11:18
-
-
Save nikkon-dev/5531916 to your computer and use it in GitHub Desktop.
Another way to shoot yourself it the foot
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
#include <iostream> | |
#include <functional> | |
#include <memory> | |
#define THIS_DECORATOR \ | |
private: \ | |
_Tx* This(){ \ | |
return static_cast<_Tx*>(this);\ | |
}\ | |
const _Tx* This() const {\ | |
return static_cast<const _Tx*>(this);\ | |
} | |
template <class _Tx> | |
struct IfDecorator | |
{ | |
THIS_DECORATOR | |
public: | |
const _Tx& If(std::function<bool(const _Tx&)> op) const | |
{ | |
if (This() == nullptr) | |
return *static_cast<const _Tx*>(nullptr); | |
if (op(*This())) | |
return *This(); | |
else | |
return *static_cast<const _Tx*>(nullptr); | |
} | |
_Tx& If(std::function<bool(const _Tx&)> op) | |
{ | |
if (This() == nullptr) | |
return *static_cast<_Tx*>(nullptr); | |
if (op(*This())) | |
return *This(); | |
else | |
return *static_cast<_Tx*>(nullptr); | |
} | |
}; | |
template <class _Tx> | |
struct WithDecorator | |
{ | |
THIS_DECORATOR | |
public: | |
const _Tx& With(std::function<void(const _Tx&)> op) const | |
{ | |
if (This() == nullptr) | |
return *static_cast<const _Tx*>(nullptr); | |
op(*This()); | |
return *This(); | |
} | |
_Tx& With(std::function<void(_Tx&)> op) | |
{ | |
if (This() == nullptr) | |
return *static_cast<_Tx*>(nullptr); | |
op(*This()); | |
return *This(); | |
} | |
}; | |
template <class _Tx> | |
struct TestDecorator | |
{ | |
THIS_DECORATOR | |
public: | |
void Func() | |
{ | |
std::cout << (this == nullptr ? "this == nullptr" : "this != nullptr") << std::endl; | |
std::cout << (This() == nullptr | |
? "static_cast<const _Tx*>(this) == nullptr" | |
: "static_cast<const _Tx*>(this) != nullptr") << std::endl; | |
} | |
}; | |
struct EmptyStruct {}; | |
template <class _Tx> | |
struct EmptyDecorator | |
: public EmptyStruct | |
{ | |
}; | |
class MyTest | |
: public EmptyDecorator<MyTest> | |
, public TestDecorator<MyTest> | |
{ | |
int a; | |
}; | |
class MyClass | |
: public IfDecorator<MyClass> | |
, public WithDecorator<MyClass> | |
{ | |
public: | |
int a; | |
}; | |
template <class _Tx> | |
struct AnyWrap | |
: public IfDecorator<AnyWrap<_Tx> > | |
, public WithDecorator<AnyWrap<_Tx> > | |
{ | |
typedef AnyWrap<_Tx> type_t; | |
AnyWrap(_Tx& value) : val(value) {} | |
AnyWrap(AnyWrap&& r) : val(r.val) {} | |
_Tx &val; | |
private: | |
AnyWrap& operator=(const AnyWrap&); //disable | |
AnyWrap(const AnyWrap&); //disable | |
}; | |
template <class _Tx> | |
AnyWrap<_Tx> make_anywrap(_Tx& val) { | |
return AnyWrap<_Tx>(val); | |
} | |
void func(MyClass &mc) | |
{ | |
mc.If([](const MyClass& v){ return v.a > 5; }) | |
.With([](MyClass& v){ v.a *= 10; }); | |
} | |
int main() | |
{ | |
MyClass mc; | |
mc.a = 10; | |
func(mc); | |
std::cout << mc.a << std::endl; | |
mc.a = 3; | |
func(mc); | |
std::cout << mc.a << std::endl; | |
(*(MyTest*)nullptr).Func(); | |
int someVal = 100; | |
auto iw = make_anywrap(someVal); | |
iw.If([](const AnyWrap<int>& v){return v.val > 10;}) | |
.With([](AnyWrap<int>& val){val.val *= 11; }); | |
std::cout << someVal << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment