Boost logo

Boost :

From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-04-12 12:52:57


AMDG

Eric Niebler wrote:
> I recently had a C++ problem and found an answer that tickled my brain.
> In the spirit of Car Talk on NPR, I thought I'd share it in the form of
> a puzzler

Another solution in the mix. All PP magic. I pushed it up to 13
parameters before msvc 9.0 failed.

In Christ,
Steven Watanabe


#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/logical/and.hpp>

#define COMMON_TYPE_LIMIT_PARAMS 4

struct default_t {};

#define IS_DEFAULT_default_t 1
#define IS_DEFAULT_T 0
#define IS_DEFAULT(x) BOOST_PP_CAT(IS_DEFAULT_, x)
#define TEST(s, state, elem) BOOST_PP_AND(state, IS_DEFAULT(elem))
#define IS_ALL_DEFAULT(seq) BOOST_PP_SEQ_FOLD_LEFT(TEST, 1, seq)

#define WITH_T(args) template<class T> struct common_type<BOOST_PP_SEQ_ENUM(args)> { typedef T type; };
#define DEFAULT(args) template<> struct common_type<BOOST_PP_SEQ_ENUM(args)> { typedef default_t type; };
#define SPECIALIZATION(r, args) BOOST_PP_IF(IS_ALL_DEFAULT(args), DEFAULT, WITH_T)(args)

template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(COMMON_TYPE_LIMIT_PARAMS, class T, default_t)>
struct common_type {};

#define PARAMETERS(z, n, data) ((T)(default_t))
BOOST_PP_SEQ_FOR_EACH_PRODUCT(SPECIALIZATION, BOOST_PP_REPEAT(COMMON_TYPE_LIMIT_PARAMS, PARAMETERS, ~))

int main() {
    typedef common_type<int, int, int>::type int1;
    typedef common_type<int, default_t, int>::type int2;
    typedef common_type<default_t, int, int, default_t>::type int3;
    //typedef common_type<default_t, int, char, default_t>::type error1;
    typedef common_type<>::type default1;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk