Boost logo

Boost Users :

Subject: Re: [Boost-users] [mpl] cross product and gcc specific compiler error
From: Josh Quigley (0zeroth_at_[hidden])
Date: 2012-05-13 19:45:26


 Hi,

 I grabbed an mpl cross product implementation (product_view) of this
 mailing list. It works fine in MSVC but fails in gcc:

// typedef boost::mpl::vector<decimal32, decimal64, decimal128>
DecimalTypes; // Original
typedef boost::mpl::vector<float, double, long double> DecimalTypes;
  // for demonstration
typedef boost::mpl::vector<int, unsigned int, long, unsigned long,
long long, unsigned long long> IntegralTypes;

typedef product_view<boost::mpl::vector<DecimalTypes, IntegralTypes> >
EachDecimalWithEachIntegralT;
BOOST_AUTO_TEST_CASE_TEMPLATE(MyTest, DecimalIntegralT,
EachDecimalWithEachIntegralT)
{
    {
        typename DecimalIntegralT::item1 r(1234567); // Fails on
gcc: no type named ‘item0’ in ‘struct boost::mpl::v_item<long long
unsigned int, boost::mpl::v_item<ext::decimal::decimal128,
boost::mpl::vector0<mpl_::na>, 0>, 0>
        typename DecimalIntegralT::item0 d(r);

        BOOST_CHECK_EQUAL(static_cast<long long>(d), r);
    }
}

 A complete listing is below. I'm wondering if there is just something
 simple that needs to be tweaked? The thing that has me really stumped
 is the type exsits in MSVC, so I'm at a bit of loss of how to proceed
 debugging.

 Any help appreciated!

//
// LISTING
//

#include <boost/mpl/vector.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/is_same.hpp>

#include <boost/function.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/test/unit_test.hpp>

namespace detail {

    using boost::mpl::at_c;
    using boost::mpl::at;
    using boost::mpl::vector3;
    using boost::mpl::true_;
    using boost::mpl::false_;
    using boost::mpl::if_;
    using boost::mpl::next;
    using boost::mpl::bool_;
    using boost::mpl::front_inserter;
    using boost::mpl::clear;
    using boost::mpl::forward_iterator_tag;
    using boost::mpl::reverse_copy;
    using boost::mpl::transform1;
    using boost::mpl::deref;
    using boost::mpl::_1;
    using boost::mpl::_2;
    using boost::mpl::int_;
    using boost::mpl::fold;
    using boost::mpl::or_;
    using boost::mpl::nested_begin_end_tag;

    template<typename S, typename O> struct state_with_overflow
    {
        typedef S state;
        typedef O overflow;
    };

    template<typename I3S> struct i3s_increment_inserter
    {
        template<typename I3, typename O> struct i3_
        {
            typedef I3 i3;
            typedef O overflow;
        };

        template<typename I3> struct incr_
        {
            typedef typename next< typename at_c< I3, 1 >::type
>::type next_;
            typedef bool_< boost::is_same< next_, typename
at_c<I3,2>::type >::value > overflow_;

            typedef i3_<
                vector3<
                typename at_c<I3,0>::type,
                typename if_< overflow_, typename at_c<I3,0>::type,
next_ >::type,
                typename at_c<I3,2>::type
>,
                overflow_
>
            type;
        };

        typedef front_inserter< typename clear<I3S>::type > base_;

        typedef state_with_overflow< typename base_::state,
true_ > state;

        struct operation
        {
            template<typename S, typename I3> struct apply
            {
                typedef typename if_<
                    typename S::overflow,
                    typename incr_<I3>::type,
                    i3_<I3,false_>
>::type next_;

                typedef state_with_overflow<
                    typename base_::operation::template apply<
typename S::state, typename next_::i3 >::type,
                    typename next_::overflow
>
                type;
            };
        };
    };

    template< typename SWO > struct product_iterator
    {
    private:

        typedef typename SWO::state I3S;

    public:
        typedef forward_iterator_tag category;

        typedef typename transform1<
            I3S, deref< at< _1, int_<1> > >
>::type type;

        typedef product_iterator<
            typename reverse_copy< I3S, i3s_increment_inserter<I3S> >::type
>
        next;
    };

    template<typename S> struct product_view
    {
    private:

        typedef typename transform1<
            S, vector3< boost::mpl::begin<_1>, boost::mpl::begin<_1>,
boost::mpl::end<_1> >
>::type
        begin_impl;

        typedef typename fold<
            S, false_,
            or_<
            _1, boost::is_same< boost::mpl::begin<_2>, boost::mpl::end<_2> >
            // empty<_2> refuses to compile on MSVC 7.1
>
>::type
        empty_result;

    public:

        typedef nested_begin_end_tag tag;

        typedef product_iterator< state_with_overflow< begin_impl,
empty_result > > begin;
        typedef product_iterator< state_with_overflow< begin_impl,
true_ > > end;
    };

}

using detail::product_view;

// typedef boost::mpl::vector<decimal32, decimal64, decimal128>
DecimalTypes; // Original
typedef boost::mpl::vector<float, double, long double> DecimalTypes;
  // for demonstration
typedef boost::mpl::vector<int, unsigned int, long, unsigned long,
long long, unsigned long long> IntegralTypes;

typedef product_view<boost::mpl::vector<DecimalTypes, IntegralTypes> >
EachDecimalWithEachIntegralT;
BOOST_AUTO_TEST_CASE_TEMPLATE(MyTest, DecimalIntegralT,
EachDecimalWithEachIntegralT)
{
    {
        typename DecimalIntegralT::item1 r(1234567); // Fails on
gcc: no type named ‘item0’ in ‘struct boost::mpl::v_item<long long
unsigned int, boost::mpl::v_item<ext::decimal::decimal128,
boost::mpl::vector0<mpl_::na>, 0>, 0>
        typename DecimalIntegralT::item0 d(r);

        BOOST_CHECK_EQUAL(static_cast<long long>(d), r);
    }
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net