Boost logo

Boost :

From: Juraj Ivančić (juraj.ivancic_at_[hidden])
Date: 2008-04-12 18:21:55


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.

Here is my solution. Not sure that it satisfies the conditions though.

Regards,
        Juraj Ivančić


#include "boost/static_assert.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/mpl/if.hpp"

class ErrorFoundTwoNonDefaultTypes {};
class Default {};

template<typename T1, typename T2>
struct FindNonDefault
{
    typedef
    typename boost::mpl::if_
    <
        boost::is_same<T1, Default>,
        T2,
        typename boost::mpl::if_
        <
            boost::is_same<T2, Default>,
            T1,
            ErrorFoundTwoNonDefaultTypes
>::type
>::type type;
};

template<typename T1, typename T2>
struct DetermineCommonBetweenTwo
{
    typedef
    typename boost::mpl::if_
    <
        boost::is_same<T1, T2>,
        T1,
        typename FindNonDefault<T1, T2>::type
>::type
    type;
};

template
<
    typename T1 ,
    typename T2 = Default,
    typename T3 = Default,
    typename T4 = Default,
    typename T5 = Default,
    typename T6 = Default,
    typename T7 = Default
>
struct DetermineCommon
{
    typedef
    typename DetermineCommonBetweenTwo
    <
        T7,
        typename DetermineCommonBetweenTwo
        <
            T6,
            typename DetermineCommonBetweenTwo
            <
                T5,
                typename DetermineCommonBetweenTwo
                <
                    T4,
                    typename DetermineCommonBetweenTwo
                    <
                        T3,
                        typename DetermineCommonBetweenTwo
                        <
                            T2,
                            T1
>::type
>::type
>::type
>::type
>::type
>::type
    type;
};


//--------------------

class A {};
class B {};

BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, Default, Default, Default>::type, Default >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , A , Default, A >::type, A >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, Default, A >::type, A >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, A >::type, A >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, A , Default, A >::type, A >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , B >::type, ErrorFoundTwoNonDefaultTypes>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, B >::type, ErrorFoundTwoNonDefaultTypes>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, Default, B >::type, ErrorFoundTwoNonDefaultTypes>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , B , Default >::type, ErrorFoundTwoNonDefaultTypes>::value ));

//--------------------

int main()
{
    return 0;
}


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