I am actually trying to see if I can get a minimal library that supports the very few operations I use from boost::fusion.
Here is what I have so far...
Seems to be doable with fully-fledged lists (that means head, tail and cons operations) and recursion. Tested with a snapshot of GCC 4.7, all the std
stuff is from
:
struct nil {};
template
struct is_nil: std::is_same {};
template
struct and_: std::true_type {};
template
struct and_
: std::integral_constant<
bool
, First::value && and_::value
> {};
template
struct not_
: std::integral_constant {};
template
struct typelist;
template
struct typelist {
typedef First head;
typedef typelist tail;
};
template
struct typelist {
typedef Last head;
typedef nil tail;
};
template
struct cons;
template
struct cons> {
typedef typelist type;
};
// workaround for:
// sorry, unimplemented: cannot expand '...' into a fixed-length argument list
template class Template, typename... T>
struct gcc_workaround {
typedef Template type;
};
namespace detail {
template
struct zip;
template
struct zip<
typename std::enable_if...>::value>::type
, Lists...
> {
typedef typelist> type;
};
template
struct zip<
typename std::enable_if>...>::value>::type
, Lists...
> {
typedef typename cons<
typelist
, typename gcc_workaround::type::type
>::type type;
};
} // detail
template
struct zip: detail::zip {};
You might want to add error checking to all this (I'm thinking of invalid instantiations that are currently simply left as incomplete types). Frankly given the amount of time it took me to figure this out, I'd suggest sticking with Boost.MPL. Things like lazy evaluation (with which I wouldn't have needed to do the SFINAE stuff) are a boon and I'd don't like reinventing them. Plus the day it's C++11 enabled you reap the best of both worlds.
I forgot to mention that Boost.MPL also has the advantages of genericity. It can work on any type that satisfies one of its sequence concept (it's also possible to non-intrusively adapt a preexisting type), whereas you force the use of typelist
.