Skip to content

Instantly share code, notes, and snippets.

@nikkon-dev
Created May 7, 2013 11:18
Show Gist options
  • Save nikkon-dev/5531916 to your computer and use it in GitHub Desktop.
Save nikkon-dev/5531916 to your computer and use it in GitHub Desktop.
Another way to shoot yourself it the foot
#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