Skip to content

Instantly share code, notes, and snippets.

@Fuyutsubaki
Last active January 3, 2016 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fuyutsubaki/8536703 to your computer and use it in GitHub Desktop.
Save Fuyutsubaki/8536703 to your computer and use it in GitHub Desktop.
ジェネリックラムダ2つを受け取りどちらか1つを返す関数型言語のif式っぽいの
//sample http://txt-txt.hateblo.jp/entry/2014/01/21/180633
#include<boost\variant\variant.hpp>
#include<type_traits>
#include<utility>
template<class F1,class F2>
class BiGenLambda
{
template<class F>
using Result_of = typename std::result_of<F>::type;
template<class ...Args>
using Check_result_of_is_same=typename std::enable_if<
std::is_same<
Result_of<F1(Args...)>, Result_of<F2(Args...)>
>::value
>::type;
public:
BiGenLambda(const F1&f)
:data_(f)
{}
BiGenLambda(const F2&f)
:data_(f)
{}
template<class F,class Result_Type>
struct Visitor
{
F f_;
using result_type = Result_Type;
Visitor(const F&f)
:f_(f)
{}
template <class T>
result_type operator()(T& x)const
{
return f_(x);
}
template <class T>
result_type operator()(const T& x)const
{
return f_(x);
}
};
template<class ...Args, class = Check_result_of_is_same<Args...>>
auto operator()(Args&&...args)
->Result_of<F1(Args...)>
{
auto vi = [&args...](auto c){return c(args...); };
using Vi = decltype(vi);
return boost::apply_visitor(Visitor<Vi, Result_of<F1(Args...)>>(vi), data_);
}
private:
boost::variant<F1, F2> data_;
};
template<class Than,class Else>
BiGenLambda<Than, Else> If(bool r, Than&&than_, Else&&else_)
{
if (r)return than_;
else return else_;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment