|
Boost : |
Subject: [boost] [mpl] cross product and gcc specific compiler error
From: Josh Quigley (0zeroth_at_[hidden])
Date: 2012-05-10 04:39:10
Hi,
A question from the grossly uninformed: 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<float, double, long double> DecimalTypes;
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. 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.
//
// 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 list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk