Boost logo

Boost Users :

From: Mark Nevill (mark.nevill_at_[hidden])
Date: 2006-03-07 08:47:38


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 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