Skip to content

Instantly share code, notes, and snippets.

@EricWF
Last active December 29, 2015 14:39
Show Gist options
  • Save EricWF/7685654 to your computer and use it in GitHub Desktop.
Save EricWF/7685654 to your computer and use it in GitHub Desktop.
Ok, so as far as I'm concerned this is currently magic. This is a copy of mpl::if_ created by https://github.com/ldionne I wanted to share because, well its beautiful...
#include <iostream>
#include <string>
using std::cout;
using std::endl;
#define UNUSED(x) ((void)x)
#define INIT() UNUSED(argc); UNUSED(argv); UNUSED(envp); cout << std::boolalpha;
namespace elib{} using namespace elib;
void mymain(int, char**, char**);
int main(int argc, char *argv[], char *envp[]) { mymain(argc, argv, envp); return 0;}
/* ------------------------------------------------------------------------- */
#include <type_traits>
#include <typeinfo>
struct na {};
struct empty_base {};
template <bool B>
using bool_ = std::integral_constant<bool, B>;
using true_ = bool_<true>;
using false_ = bool_<false>;
template <class T>
struct identity
{
using type = T;
};
template <class Cond, class Then>
struct branch
{
using condition = Cond;
using then = Then;
};
template <class ...Branches> struct evaluate;
template <class First, class ...Rest>
struct evaluate<First, Rest...>
: std::conditional<
First::condition::type::value
, identity<typename First::then>
, evaluate<Rest...>
>::type
{};
template <class ...Branches>
struct accumulate
{
private:
template <class Cond, class If, class Else = na>
struct make_else_if
: identity<
evaluate<Branches..., branch<Cond, If>, branch<true_, Else>>
>
{};
template <class Cond, class Then>
struct make_else_if<Cond, Then>
: identity<
accumulate<Branches..., branch<Cond, Then>>
>
{};
public:
template <class Cond, class Then, class Else = na>
using else_if = typename make_else_if<Cond, Then, Else>::type;
template <bool Cond, class Then, class Else = na>
using else_if_c = else_if<bool_<Cond>, Then, Else>;
template <class Else>
using else_ = evaluate<Branches..., branch<true_, Else>>;
};
template <class, class = na, class = na>
struct if_;
template <class Cond, class Then, class Else>
struct if_;
template <class If, class Cond>
struct if_<If,Cond>;
template <class Cond, class Then, class Else>
struct if_
: accumulate<>::template else_if<Cond, Then, Else>
{};
template <class Cond>
struct if_<Cond>
: if_<Cond, identity<void>, empty_base>::type
{};
template <class Cond, class Then>
struct if_<Cond, Then>
: accumulate<>::template else_if<Cond, Then>
{};
//////////////////////////////////////////////////////////////////////////////
//
// LOOK HERE
//
//////////////////////////////////////////////////////////////////////////////
using type =
if_<false_, void>::
else_if<false_, int>::
else_<char>;
/*----------------------------------------------------------------- */
void mymain(int argc, char *argv[], char *envp[]) { INIT();
cout <<
std::is_same<typename type::type, char>::value
<< endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment