Last active
December 29, 2015 14:39
-
-
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...
This file contains 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 <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