Boost logo

Boost :

From: Steven Watanabe (steven_at_[hidden])
Date: 2007-02-07 14:41:55


AMDG

Janek Kozicki <janek_listy <at> wp.pl> writes:

>
> Matthias Schabel said: (by the date of Tue, 6 Feb 2007 16:04:15 -0700)
>
> Hi,
>
> I still haven't looked at it, I should have time for that in few weeks.
>
> > In any case, for most projects, you would just throw the
> > quantities you want into a precompiled header file, so it should
> > really only be a one-time cost...
>
> But I wanted to ask if you have some example demonstrating this, or
> is it explained in docs. Because frankly speaking I don't understand
> what you mean here. I type 'make clean' and then I type 'make'.
> Nothing is precompiled at this stage, so how I can save time?
>
> My app is huge, and it already takes long to compile, so I prefer to
> use this "one-time cost" solution.
>

The following replacement for dimension speeds up my compilies by about 5x
with msvc.

struct sort_dims_list_end {
    enum { size = 0 };
};
template<class T, class Next = sort_dims_list_end>
struct sort_dims_list {
    typedef T item;
    typedef Next next;
    enum { size = Next::size + 1 };
};

template<class Sequence, class T>
struct replace_front {
    typedef sort_dims_list<
        typename static_add<T, typename Sequence::item>::type,
        typename Sequence::next
> type;
};

template<class Sequence, class T>
struct insert_new {
    typedef typename boost::mpl::if_<boost::is_same<typename get_tag<typename
Sequence::item>::type, static_rational<0> >,
        typename Sequence::next,
        Sequence
>::type type1;
    typedef sort_dims_list<T, type1> type;
};

template<class Sequence, class T>
struct sort_dims_insert {
    typedef typename
boost::mpl::eval_if_c<(Sequence::item::tag_type::value::type::value ==
T::tag_type::value::type::value),
        replace_front<Sequence, T>,
        insert_new<Sequence, T>
>::type type;
};

template<class T>
struct sort_dims_insert<sort_dims_list_end, T> {
    typedef typename sort_dims_list<T> type;
};

template<class Out1, class Out2>
struct partition_dims_state {
    typedef Out1 out1;
    typedef Out2 out2;
};
template<bool>
struct partition_dims_state_insert;
template<>
struct partition_dims_state_insert<true> {
    template<class State, class T>
    struct apply {
        typedef partition_dims_state<sort_dims_list<T, typename State::out1>,
typename State::out2> type;
    };
};
template<>
struct partition_dims_state_insert<false> {
    template<class State, class T>
    struct apply {
        typedef partition_dims_state<typename State::out2, sort_dims_list<T,
typename State::out1> > type;
    };
};

template<class Begin, class End, class State, long Value>
struct partition_dims_forward_impl {
    typedef typename Begin::item::tag_type::value::type val;
    typedef typename partition_dims_forward_impl<
        typename Begin::next, End,
        typename partition_dims_state_insert<((val::value) < Value)>::template
apply<State, typename Begin::item>::type,
        Value
>::type type;
};

template<class End, class State, long Value>
struct partition_dims_forward_impl<End, End, State, Value> {
    typedef State type;
};

template<class Sequence, class Output>
struct sort_dims_forward;

template<int N>
struct sort_dims_forward_impl {
template<class Begin, class End, class Output>
    struct apply {
        typedef typename
            partition_dims_forward_impl<
                typename Begin::next, End,
                partition_dims_state<sort_dims_list_end, sort_dims_list_end>,
                Begin::item::tag_type::value::type::value
>::type partitioned;
        typedef typename sort_dims_forward<typename partitioned::out1,
Output>::type step1;
        typedef typename sort_dims_insert<step1, typename Begin::item>::type step2;
        typedef typename sort_dims_forward<typename partitioned::out2,
step2>::type type;
    };
};

template<>
struct sort_dims_forward_impl<0> {
template<class Begin, class End, class Output>
    struct apply {
        typedef Output type;
    };
};

template<>
struct sort_dims_forward_impl<1> {
template<class Begin, class End, class Output>
    struct apply {
        typedef typename sort_dims_insert<Output, typename Begin::item>::type type;
    };
};

template<class Sequence, class Output>
struct sort_dims_forward {
    typedef typename sort_dims_forward_impl<Sequence::size>::template apply<
        Sequence,
        sort_dims_list_end,
        Output
>::type type;
};

template<int N>
struct remove_dimensionless {
    template<class Begin, class Out>
    struct apply {
        typedef typename boost::mpl::deref<Begin>::type deref;
        typedef typename boost::mpl::if_<boost::is_same<typename
deref::tag_type, dimensionless_type>,
            Out,
            sort_dims_list<deref, Out>
>::type type1;
        typedef typename remove_dimensionless<N - 1>::template apply<typename
boost::mpl::next<Begin>::type, type1>::type type;
    };
};

template<>
struct remove_dimensionless<0> {
    template<class Begin, class Out>
    struct apply {
        typedef Out type;
    };
};

template<class Sequence>
struct sort_dims_to_mpl_list {
    typedef typename boost::mpl::push_front<typename
sort_dims_to_mpl_list<typename Sequence::next>::type, typename
Sequence::item>::type type;
};
template<>
struct sort_dims_to_mpl_list<sort_dims_list_end> {
    typedef mpl::list0<> type;
};

/// reduce dimension list to cardinal form

/// This algorithm collapses duplicate unit tags, strips resulting dimensionless
/// tags, and sorts the resulting list by the tag ordinal value. It guarantees
/// that two dimension lists that resolve to the same dimension are represented
/// by an identical type
template<typename Seq>
struct dimension
{
    typedef typename remove_dimensionless<
        boost::mpl::size<Seq>::value
>::template apply<typename boost::mpl::begin<Seq>::type,
sort_dims_list_end>::type sequence;
    
    typedef typename sort_dims_forward<sequence, sort_dims_list_end>::type type2;

    typedef typename sort_dims_to_mpl_list<type2>::type type3;
    
    typedef typename mpl::if_<mpl::empty<type3>, dimensionless_type,
type3>::type type;
};

In Christ,
Steven Watanabe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk