Boost logo

Boost :

From: Juraj Ivančić (juraj.ivancic_at_[hidden])
Date: 2008-04-13 08:29:59


Juraj Ivančić wrote:
> 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.

Here I added a minor improvement which did not occur to me until reading
latest solutions from Daniel Frey.

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,
    typename T8 = Default
>
struct DetermineCommon
{
    typedef
    typename DetermineCommonBetweenTwo
    <
        typename DetermineCommonBetweenTwo
        <
            typename DetermineCommonBetweenTwo<T1,T2>::type,
            typename DetermineCommonBetweenTwo<T3,T4>::type
>::type,
        typename DetermineCommonBetweenTwo
        <
            typename DetermineCommonBetweenTwo<T5,T6>::type,
            typename DetermineCommonBetweenTwo<T7,T8>::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