[mpl] random sequence generator, whats wrong?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[mpl] random sequence generator, whats wrong?

Mark Nevill
Hi,
I am trying to make a template for building sequences of random numbers
using Boost.Mpl, but apparently I haven't quite got the hang of it yet
;). Below is my code (adapted from the Boost.Random docs) and the
compiler output (GCC v 3.4.2), I seem to have misunderstood the usage of
mpl::first and mpl::second in lambdas or something. Can someone clarify
what I've done wrong? The whole construct should be invoked with
something like
typedef utils::make_random_sequence<vector0_c<unsigned long>,
utils::minstd_rand, 10>::type random_vector;
to generator a vector_c of 10 random numbers.
Thanks,
Mark

#include <cstdlib>
#include <boost/static_assert.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/modulus.hpp>
#include <boost/mpl/iter_fold.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/type_traits/is_integral.hpp>

namespace utils
{
    using namespace boost::mpl;

    template<class T, class Formula, T seed>
    struct random :
        integral_c<
            T,
            template Formula::apply<seed>::value
        >
    {
        typedef random<T, Formula, value> next;
        template<T new_seed>
            struct reseed
        {
            typedef random<T, Formula, new_seed> type;
        };
    };

    template<class IntType, IntType a, IntType c, IntType m>
    struct linear_congruential
    {
        BOOST_STATIC_ASSERT(boost::is_integral<IntType>::value);
        typedef IntType value_type;
        template<IntType seed>
            struct apply : integral_c<IntType, (a * seed + c) % m>
        {
        };
    };

    typedef random<
        long,
        linear_congruential<long, 16807L, 0, 2147483647L>,
        1043618065L
    > minstd_rand0;
    typedef random<
        long,
        linear_congruential<long, 48271L, 0, 2147483647L>,
        399268537L
    > minstd_rand;

    template<class integral_sequence, class generator, size_t size>
    struct make_random_sequence
    {
        typedef typename iter_fold<
            range_c<size_t, 1, size>,
            pair<
                typename erase<
                    integral_sequence,
                    begin<integral_sequence>,
                    end<integral_sequence>
                >::type,
                generator
            >,
            pair<
                push_back<
                    first<_1>,
                    second<_1>
                >::type,
                second<_1>::next
            >
        >::type type;
    };
}

28: error: missing `>' to terminate the template argument list
28: error: template argument 2 is invalid
28: error: expected `{' before "template"
28: error: expected unqualified-id before "template"
28: error: expected `;' before "template"
C:/Boost/include/boost-1_33/boost/mpl/pair.hpp: In instantiation of
`boost::mpl::first<mpl_::_1>':
C:/Boost/include/boost-1_33/boost/mpl/aux_/has_tag.hpp:20:  
instantiated from `boost::mpl::aux::has_tag<boost::mpl::first<mpl_::_1>,
mpl_::bool_< false> >'
C:/Boost/include/boost-1_33/boost/mpl/sequence_tag.hpp:115:  
instantiated from `boost::mpl::sequence_tag<boost::mpl::first<mpl_::_1> >'
C:/Boost/include/boost-1_33/boost/mpl/push_back.hpp:32:   instantiated
from `boost::mpl::push_back<boost::mpl::first<mpl_::_1>,
boost::mpl::second<mpl_::_1> >'
85:   instantiated from here
C:/Boost/include/boost-1_33/boost/mpl/pair.hpp:43: error: no type named
`first' in `struct mpl_::_1'
85: error: `type' is not a member of
`boost::mpl::push_back<boost::mpl::first<mpl_::_1>,
boost::mpl::second<mpl_::_1> >'
85: error: `type' is not a member of
`boost::mpl::push_back<boost::mpl::first<mpl_::_1>,
boost::mpl::second<mpl_::_1> >'
C:/Boost/include/boost-1_33/boost/mpl/pair.hpp: In instantiation of
`boost::mpl::second<mpl_::_1>':
86:   instantiated from here
C:/Boost/include/boost-1_33/boost/mpl/pair.hpp:56: error: no type named
`second' in `struct mpl_::_1'
86: error: `next' is not a member of `boost::mpl::second<mpl_::_1>'
86: error: `next' is not a member of `boost::mpl::second<mpl_::_1>'
88: error: template argument 1 is invalid
88: error: template argument 2 is invalid
88: error: template argument 3 is invalid
88: error: `type' does not name a type
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [mpl] random sequence generator, whats wrong?

David Abrahams
Mark Nevill <[hidden email]> writes:

> 28: error: missing `>' to terminate the template argument list

Looks like a compiler bug to me.
Try using an intermediate typedef to access T on this line.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [mpl] random sequence generator, whats wrong?

Vinzenz 'evilissimo' Feenstra-3
David Abrahams schrieb:
> Mark Nevill <[hidden email]> writes:
>
>> 28: error: missing `>' to terminate the template argument list
>
> Looks like a compiler bug to me.
> Try using an intermediate typedef to access T on this line.
>

I don't think so.

He wrotes:

    template Formula::apply<seed>::value

but it should be

    Forumula::template apply<seed>::value

BR
Vinzenz

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users